Haskell. "Failed to take (t ~ [t]) out of context (Eq t)"

Just learn haskell on your own and you can't solve this problem. These are codes.

subst :: Eq t=>t->t->[t]->[t]
subst a b [xs]=[if x==a then b else x | x <- xs]

      

The error is below.

subst.hs:2:46:
    Could not deduce (t ~ [t])
    from the context (Eq t)
      bound by the type signature for
                 subst :: Eq t => t -> t -> [t] -> [t]
      at subst.hs:1:10-29
      ‘t’ is a rigid type variable bound by
          the type signature for subst :: Eq t => t -> t -> [t] -> [t]
          at subst.hs:1:10
    Relevant bindings include
      xs :: t (bound at subst.hs:2:12)
      b :: t (bound at subst.hs:2:9)
      a :: t (bound at subst.hs:2:7)
      subst :: t -> t -> [t] -> [t] (bound at subst.hs:2:1)
    In the expression: xs
    In a stmt of a list comprehension: x <- xs

      

The problem I think is that haskell cannot guarantee that an element from [t] matches t. I'm not sure. And I want to know how to solve this problem.

+3


source to share


2 answers


you only have one [..]

wrap for many:

subst :: Eq t=>t->t->[t]->[t]
subst a b xs = [if x==a then b else x | x <- xs]

      



just xs

not[xs]

The reason is simple: if you are writing [xs]

, you tell Haskell to expect a list with one entry xs

, and it will try to match it with a pattern - after that, you will say to pull values x

from xs

( x <- xs

), which tells Haskell that it xs

should be some kind of list. so in the end it will take t

as some list t ~ [s]

. But then you go on and check x == a

both here x :: s

and a :: t

ending with an error like now [s] ~ t ~ s

.

+6


source


In the parameter list, you write [xs]

. This is a pattern that matches a list containing exactly one element, which will then be named xs

. This has two consequences:



  • This is not an exhaustive pattern match and will not work at runtime if the given list has zero or more elements. Since you want the same code to execute regardless of the length of the list, you want the pattern to always match, for example xs

    without parentheses.
  • Since xs

    in [xs]

    refers to a single element of the list, its type t

    is not [t]

    . However, you use it as if its type were [t]

    , which makes Haskell conclude that it t

    should be equal [t]

    (an operator is ~

    used in Haskell to mean that two types are equal), which leads to the somewhat confusing type error you get.
+3


source







All Articles