Haskell: type declaration in `where`

I have an example of a function in which I cannot write a type in where . replace is a function that replaces all Xs with Ys in a given list.

 replace :: (Eq a) => a -> a -> [a] -> [a] replace xy xs = map helper xs where helper :: (Eq a) => a -> a helper = (\el -> if el == x then y else el) 

When I try to compile this function, I get an error message:

 ProblemsArithmetics.hs:156:31: Could not deduce (a ~ a1) from the context (Eq a) bound by the type signature for replace :: Eq a => a -> a -> [a] -> [a] at ProblemsArithmetics.hs:152:12-41 or from (Eq a1) bound by the type signature for helper :: Eq a1 => a1 -> a1 at ProblemsArithmetics.hs:155:15-30 'a' is a rigid type variable bound by the type signature for replace :: Eq a => a -> a -> [a] -> [a] at ProblemsArithmetics.hs:152:12 'a1' is a rigid type variable bound by the type signature for helper :: Eq a1 => a1 -> a1 at ProblemsArithmetics.hs:155:15 Relevant bindings include el :: a1 (bound at ProblemsArithmetics.hs:156:16) helper :: a1 -> a1 (bound at ProblemsArithmetics.hs:156:5) xs :: [a] (bound at ProblemsArithmetics.hs:153:13) y :: a (bound at ProblemsArithmetics.hs:153:11) x :: a (bound at ProblemsArithmetics.hs:153:9) replace :: a -> a -> [a] -> [a] (bound at ProblemsArithmetics.hs:153:1) In the second argument of '(==)', namely 'x' In the expression: el == x 

At the same time, if I lower

 helper :: (Eq a) => a -> a 

code compiled in order.

Although I understand the logic of this ( a in replace type declaration and a in helper , type declaration is different from a s), and there are at least 2 workarounds (omit type declaration or pass x and y as parameters of helper function), my question is:

Is there a way to tell the compiler that I mean the same type in type declarations?

+5
source share
1 answer

If you enable ScopedTypeVariables and enter a type variable with forall , then it will become visible in the inner area.

 {-# LANGUAGE ScopedTypeVariables #-} replace :: forall a. (Eq a) => a -> a -> [a] -> [a] replace xy xs = map helper xs where helper :: a -> a helper = (\el -> if el == x then y else el) 
+10
source

Source: https://habr.com/ru/post/1216166/


All Articles