Haskell 怪异无法匹配类型错误
我有一个简单的单行函数:Haskell 怪异无法匹配类型错误,haskell,types,fold,unfold,Haskell,Types,Fold,Unfold,我有一个简单的单行函数: revRange :: (Char,Char) -> [Char] revRange t = unfoldr (\b -> if b == (pred (fst t)) then Nothing else Just (b, pred b)) (snd t) 它运行良好: *Main Data.List> revRange ('a', 'f') "fedcba" 然后我想将Unfover lambda提取为唯一函数: revRange :: (Cha
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (\b -> if b == (pred (fst t)) then Nothing else Just (b, pred b)) (snd t)
它运行良好:
*Main Data.List> revRange ('a', 'f')
"fedcba"
然后我想将Unfover lambda提取为唯一函数:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t)) then Nothing else Just (b, pred b)) (snd t)
现在,我有一个奇怪的错误:
Couldn't match type `Char' with `(Char, Char)'
Expected type: (Char, Char) -> Maybe (Char, (Char, Char))
Actual type: (Char, Char) -> Maybe (Char, Char)
In the first argument of `unfoldr', namely `fun'
In the expression: unfoldr fun t
首先,格式化代码:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t))
then Nothing
else Just (b, pred b)) (snd t)
接下来,使用以下命令再次检查展开器的类型:
接下来,给fun添加一个类型签名,这样GHC就会告诉您问题所在。根据展开器的类型,fun应具有以下类型:
b ~ Char
a ~ Char
fun :: Char -> Maybe (Char, Char)
因为您在原始示例中使用snd t展开程序
我通常喜欢验证小片段,因此我们可以删除foo的定义,只使用类型签名:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun:: Char -> Maybe (Char, Char)
fun b = error ""
GHC抱怨t的类型是Char,Char,但fun希望类型是Char。您调用了Unfolder fun t,而不是原始示例中的Unfolder fun snd t。将该部分从“乐趣”移动到revRange:
接下来,再次添加乐趣的定义。我们可以删除lambda并将b作为fun的正常参数:
我们立刻看到了另一个明显的问题:乐趣需要两个论点,但签名上说它应该只需要一个
由于t在原始lambda中是一个常数,我们可以通过在revRange中部分应用fun来解决此问题,因此最终答案是:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (fun t) (snd t)
fun:: (Char, Char) -> Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t))
then Nothing
else Just (b, pred b)
为了回应你的评论,你想写
revRange :: (Char,Char) -> [Char]
revRange = unfoldr fun2
使用与上面相同的方法,在展开器的签名中,我们需要b~Char、Char和a~Char。所以我们想要fun2的型号
fun2 :: ((Char,Char) -> Maybe (Char, (Char, Char)))
我将把fun2的定义留给一个练习。作为提示,我建议采用该对的第一部分为常量并保持fst的约定。首先,格式化代码:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t))
then Nothing
else Just (b, pred b)) (snd t)
接下来,使用以下命令再次检查展开器的类型:
接下来,给fun添加一个类型签名,这样GHC就会告诉您问题所在。根据展开器的类型,fun应具有以下类型:
b ~ Char
a ~ Char
fun :: Char -> Maybe (Char, Char)
因为您在原始示例中使用snd t展开程序
我通常喜欢验证小片段,因此我们可以删除foo的定义,只使用类型签名:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun:: Char -> Maybe (Char, Char)
fun b = error ""
GHC抱怨t的类型是Char,Char,但fun希望类型是Char。您调用了Unfolder fun t,而不是原始示例中的Unfolder fun snd t。将该部分从“乐趣”移动到revRange:
接下来,再次添加乐趣的定义。我们可以删除lambda并将b作为fun的正常参数:
我们立刻看到了另一个明显的问题:乐趣需要两个论点,但签名上说它应该只需要一个
由于t在原始lambda中是一个常数,我们可以通过在revRange中部分应用fun来解决此问题,因此最终答案是:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (fun t) (snd t)
fun:: (Char, Char) -> Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t))
then Nothing
else Just (b, pred b)
为了回应你的评论,你想写
revRange :: (Char,Char) -> [Char]
revRange = unfoldr fun2
使用与上面相同的方法,在展开器的签名中,我们需要b~Char、Char和a~Char。所以我们想要fun2的型号
fun2 :: ((Char,Char) -> Maybe (Char, (Char, Char)))
我将把fun2的定义留给一个练习。作为提示,我建议采用惯例,即配对的第一部分是常量,并保持fst。看起来好像包含了snd t,这是原始版本中Unfover的第二个参数,在fun中,这应该只是lambda表达式?看起来好像包含了snd t,哪一个是原始版本中Unfover的第二个参数,在fun中,这应该只是lambda表达式?我还有一个问题。有可能把snd和t转移到娱乐中去吗?我想看到的第一行是revRange=unfover。我还有一个问题。有可能把snd和t转移到娱乐中去吗?我想看到第一行是revRange=unfover。