Search code examples
haskellghci

ghci function multiple variable mentions in declarations not accepted


I'm trying to learn Haskell, so I tried this:

$ ghci
GHCi, version 8.10.7: https://www.haskell.org/ghc/  :? for help
Prelude> :set +m
Prelude> let element :: (Eq a) => [a] -> a -> Bool   
Prelude|     element [] _ = False
Prelude|     element [x:_] x = True
Prelude|     element [_:xs] x = element xs x
Prelude| 

<interactive>:4:14: error:
    • Conflicting definitions for ‘x’
      Bound at: <interactive>:4:14
                <interactive>:4:19
    • In an equation for ‘element’
Prelude> 

So on line 4, why doesn't it just use the first binding, and force equivalence? This is obviously a toy problem; I know I can import list functions and use element = flip elem

My next attempt wil use guards...

Stackoverflow won't post this unless I include more "details" - let me know what details I'm missing and I'll add them in the comments.


Solution

  • x is not a variable; it's a pattern. Patterns have to be unique within a single definition so that it isn't ambiguous which value should be assigned to the name. The kind of unification you ask about is likely more complicated than it would be worth to avoid an explicit workaround.

    If you want to check that the head of the first argument is equal to the second argument, use separate patterns and compare them explicitly in a guard or in the definition itself.

    let element :: (Eq a) => [a] -> a -> Bool
        element [] _ = False
        element (x:xs) y | x == y = True
                         | otherwise = element xs y