【问题标题】:Could not deduce ....context Ord Haskell无法推断 ....context Ord Haskell
【发布时间】:2013-12-01 00:46:10
【问题描述】:

出于学习目的,我尝试将 2 个列表压缩在一起,前提是两个列表的长度匹配。 (必须是相同的长度)不幸的是,它拒绝编译。 我认为签名有问题..谢谢您的期待。 这是我的代码:

ziptogether :: (Ord a) => [a] -> [a] -> [a]
ziptogether [] [] = 0
ziptogether (x:xs) (y:ys) 
   | length(x:xs) == length(y:ys) = zip (x:xs) (y:xs)
   | otherwise = error "not same length"

错误:

     Could not deduce (a ~ (a, a))
     from the context (Ord a)
      bound by the type signature for
                ziptogether :: Ord a => [a] -> [a] -> [a]
      at new.hs:2:16-43
         `a' is a rigid type variable bound by
         the type signature for ziptogether :: Ord a => [a] -> [a] -> [a]
         at new.hs:2:16
    Expected type: [a]
     Actual type: [(a, a)]
    In the return type of a call of `zip'
    In the expression: zip (x : xs) (y : xs)
    In an equation for `ziptogether':
    ziptogether (x : xs) (y : ys)
      | length (x : xs) == length (y : ys) = zip (x : xs) (y : xs)
      | otherwise = error "not same length"

【问题讨论】:

    标签: haskell


    【解决方案1】:

    有几个问题。您的类型签名说您获取两个列表并返回另一个,您的第一个问题是

     ziptogether [] [] = 0
    

    所以这需要元素并返回......一个数字。我想你想要

     ziptogether [] [] = []
    

    下一个问题是你递归调用zip,它返回[(a, a)]。您可以将类型签名更改为

     ziptogether :: [a] -> [a] -> [(a, a)]
     ziptogether [] [] = []
     ziptogether (x:xs) (y:ys) | length xs == length ys = zip (x:xs) (y:ys)
                               | otherwise = error "Not the same length"
    

    当然你可以在这里去掉多余的情况

     ziptogether xs ys | length xs == length ys = zip xs ys
                       | otherwise              = error "Not the same length"
    

    请注意,我们不需要Ord 约束。仅当您计划使用 < 或类似的操作时才需要它。

    【讨论】:

    • 非常感谢!我有一个问题,你为什么忽略了“Ord(a)”。我们不是在两个列表之间进行比较吗?我们正在比较两者的长度。为什么这里不需要Ord?
    • @user2938633 两个列表的长度是Int,列表中的内容无关紧要,它的长度只是一个数字。如果我们想比较元素,那么我们需要一些约束。但我们没有,所以我们没有。
    • 好的,明白了,谢谢。第二个问题。它现在可以编译,但它并没有使它成为它应该做的事情。我在你更正后更改了我的代码,当我输入 ziptogether [1,2,3,4] [5,6,7,8] 它给了我 [ (1,1), (2,2) (3,3) , (4,4) ] 结果。为什么?
    • @user2938633 恐怕我无法复制这种行为ideone.com/xAQmDH
    • 哦,大错特错。不小心我写了 zip xs xs 而不是 zip xs ys。真丢人!不过,非常感谢jozefg。又帮了我很多!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多