亲自学习haskell,无法解决这个问题。这些是代码。
subst :: Eq t=>t->t->[t]->[t]
subst a b [xs]=[if x==a then b else x | x <- xs]
错误如下。
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
问题,我想,haskell无法确保[t]中的元素与t匹配。我不确定。我想知道如何解决这个问题。
答案 0 :(得分:6)
你只有一个[..]
包装给许多人:
subst :: Eq t=>t->t->[t]->[t]
subst a b xs = [if x==a then b else x | x <- xs]
只是xs
而不是[xs]
原因很简单:如果你写[xs]
,你告诉Haskell期望一个包含单个条目xs
的列表,它会尝试模式匹配它 - 之后这告诉它从x
(xs
)中提取值x <- xs
,告诉Haskell xs
必须是某种列表本身。所以最后它会假设t
为某个列表t ~ [s]
。但接下来,请继续检查x == a
以及x :: s
和a :: t
,以错误结束,现在为[s] ~ t ~ s
。
答案 1 :(得分:3)
在参数列表中编写[xs]
。这是一个匹配包含一个元素的列表的模式,然后将其称为xs
。这有两个后果:
xs
没有括号。xs
中的[xs]
引用了列表中的单个元素,因此其类型为t
,而不是[t]
。但是你使用它就好像它的类型是[t]
一样,这导致Haskell断定t
必须等于[t]
(在Haskell中使用~
运算符来表示这两种类型是等于),这会导致你得到的有点混乱的类型错误。