Haskell编译器如何推断这些(列表列表)类型?

时间:2018-01-20 10:31:03

标签: haskell

我试图创建一个将相同元素打包到列表中的函数。这是一个训练问题,所以我想让自己的溶剂工作。我不是在寻找解决问题的替代方法,我只想了解为什么这段代码无法编译。

这里的功能是:

pack :: Eq a => [a] -> [[a]]
pack xs = let packHelper acc [] = acc
              packHelper acc zs = let splitOff = takeWhile (\y -> y == (head zs)) zs
                                  in  packHelper ( (splitOff:acc) (drop (length splitOff) zs) )
          in  packHelper [[]] xs 

测试用例:

pack ['a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e']
==
["aaaa","b","cc","aa","d","eeee"]

当前实现无法编译并出现此错误:

main.hs:109:15: error:
* Couldn't match type `[a1] -> [[a1]]' with `[[a1]]'
  Expected type: [[a1]] -> [[a1]]
    Actual type: [[a1]] -> [a1] -> [[a1]]
* In the expression:
    let
      packHelper acc [] = acc
      packHelper acc zs
        = let ...
          in packHelper ((splitOff : acc) (drop (length splitOff) zs))
    in packHelper [[]] xs
  In an equation for `pack':
      pack xs
        = let
            packHelper acc [] = acc
            packHelper acc zs = ...
          in packHelper [[]] xs
* Relevant bindings include
    packHelper :: [[a1]] -> [[a1]]
      (bound at main.hs:109:15)
    |
109 | pack xs = let packHelper acc [] = acc
    |               ^^^^^^^^^^^^^^^^^^^^^^^^...

main.hs:111:52: error:
* Couldn't match expected type `[a1] -> [[a1]]'
              with actual type `[[a1]]'
* The function `splitOff : acc' is applied to one argument,
  but its type `[[a1]]' has none
  In the first argument of `packHelper', namely
    `((splitOff : acc) (drop (length splitOff) zs))'
  In the expression:
    packHelper ((splitOff : acc) (drop (length splitOff) zs))
* Relevant bindings include
    splitOff :: [a1]
      (bound at main.hs:110:39)
    zs :: [a1]
      (bound at main.hs:110:30)
    acc :: [[a1]]
      (bound at main.hs:110:26)
    packHelper :: [[a1]] -> [[a1]]
      (bound at main.hs:109:15)
    |
111 |                                   in  packHelper ( (splitOff:acc) 
(drop (length splitOff) zs) )
    |                                                    
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

main.hs:112:15: error:
* Couldn't match expected type `[a] -> [[a]]'
              with actual type `[[a0]]'
* The function `packHelper' is applied to two arguments,
  but its type `[[a0]] -> [[a0]]' has only one
  In the expression: packHelper [[]] xs
  In the expression:
    let
      packHelper acc [] = acc
      packHelper acc zs
        = let ...
          in packHelper ((splitOff : acc) (drop (length splitOff) zs))
    in packHelper [[]] xs
* Relevant bindings include
    xs :: [a]
      (bound at main.hs:109:6)
    pack :: [a] -> [[a]]
      (bound at main.hs:109:1)
    |
112 |           in  packHelper [[]] xs 
    |               ^^^^^^^^^^^^^^^^^^

为什么编译器期望[[a1]] - > [[a1]]而不是[[a1]] - > [a1] - > [[a1]] for packHelper?

0 个答案:

没有答案