如果项目“X”连续出现两次,或者B)项目本身,如果它不与副本相邻。
示例:
encode ["A", "A", "A", "B", "C", "C", "B", "B", "B", "D"]
> [(3, "A"), "B", (2, "C"), (3, "B"), "D"]
适当的签名是什么?我试过这个:
data listItem a = (Integer, a) | a
encode :: (Eq a) => [a] -> [listItem a]
但是我收到了这个错误:
parse error in constructor in data/newtype declaration: (Integer, a)
我偷看了这个问题的解决方案,它给了我这种类型的签名:
data ListItem a = Single a | Multiple Int a
deriving (Show)
encode :: Eq a => [a] -> [ListItem a]
但是在使用这个简单的测试时
encode [x] = [x]
我收到错误:
Could not deduce (a ~ ListItem a)
from the context (Eq a)
bound by the type signature for
encode :: Eq a => [a] -> [ListItem a]
at 99problems.hs:117:19-45
`a' is a rigid type variable bound by
the type signature for
encode :: Eq a => [a] -> [ListItem a]
at 99problems.hs:117:19
In the expression: x
In the expression: [x]
此问题的正确类型签名是什么?
答案 0 :(得分:10)
根据我的理解,“99问题”集最初是为Prolog编写的,然后翻译成Lisp。那时......啊......音译到Haskell。不幸的是,在Lisp中有意义的事情在Haskell中并不总是那么有意义,所以从字面上理解问题描述会让你陷入困境。提示告诉你的是,不是试图编写一个产生类似[(3, "A"), "B", (2, "C"), (3, "B"), "D"]
的列表的函数,而这在Haskell中是不可能的,你应该设法生成一个类似[Multiple 3 "A", Single "B", Multiple 2 "C", Multiple 3 "B", Single "D"]
的列表。
建议的类型签名是正确的;你只需编写代码来匹配它。
正如我所说,99问题集并不是非常Haskellian。它并不尊重Haskell代码的通常惯用风格,所以你应该不将它作为如何编写Haskell代码的模型。例如,一个Haskell程序员(或者,对于这个问题,一个理智的Lisp程序员)可能只会产生一个(Int,a)
对的列表,而不会打扰那些使一切更复杂,更不均匀的单个/多个废话。并且很可能在实际应用中速度较慢。
“99问题”的其他几种方式往往会打破Haskell编程的通常期望:
它倾向于以不同于Haskell程序员的顺序放置参数。如果函数采用列表和数字,Haskell程序员几乎总是将数字放在第一位,列表放在第二位; “99问题”倾向于反过来做。
Haskell程序员几乎总是对列表,数组等使用基于0的索引。“99问题”似乎喜欢基于1的索引。