I have an example of function, in which I can't write a type in where
clause. replace
is a function, that replaces all Xs by Ys in a given list.
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y 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:
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 omit
helper :: (Eq a) => a -> a
the code is compiled fine.
While I understand the logic behind it (a
in replace
type declaration and a
in helper
type declaration are different a
s), and there are at least 2 workarounds (omit type declaration or pass x
and y
as parameters to helper
function), my question is:
Is there any way to tell the compiler that I mean the same type in both type declarations?
If you enable ScopedTypeVariables
and introduce a type variable with a forall
, then it becomes visible in the inner scope.
{-# LANGUAGE ScopedTypeVariables #-}
replace :: forall a. (Eq a) => a -> a -> [a] -> [a]
replace x y xs = map helper xs
where
helper :: a -> a
helper = (\el -> if el == x then y else el)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With