Haskell - 在“无法匹配预期类型”的情况下的模式匹配

时间:2013-09-15 18:29:43

标签: haskell pattern-matching case-statement

我有一个类似于的自定义数据类型:

data Token = Number Int
           | Otherthings

我希望能够以一种方式使用“数字”而在另一种方式中使用其他东西。所以我可以成功创建一个案例陈述,如:

parse x = case x of
    Number y -> y

然后成功地采取了:

let x = Number 7 in parse x

并评估为7.但是,当我尝试将“解析”功能更改为:

parse [] = []
parse (x:xs) = case x of
    Number y -> y

我收到错误:

Couldn't match expected type `[a0]' with actual type `Int'
In the expression: y
In a case alternative: Number y -> y
In the expression: case x of { Number y -> y }

为什么这不能以这种方式工作以及解决这个问题的正确方法是什么?非常感谢!

4 个答案:

答案 0 :(得分:6)

分别查看parse定义的两个部分的类型。

parse :: [a] -> [b] -- both the []'s are lists of some (possibly different) type
parse [] = []

parse :: [Token] -> Int -- y, the function's return value, is an Int.
parse (x:xs) = case x of
    Number y -> y

你可以看到a ~ Token工作正常,[b] ~ Int不起作用:Int不是某个列表。 (错误消息正在使用a0,我正在使用b。)

解决这个问题的方法是考虑你希望parse返回什么类型,并确保其定义的所有部分都与之匹配。我不确定你想要parse做什么,所以我不能在那里给出明确的答案。

答案 1 :(得分:2)

parse的两个定义有不同的类型。 parse []返回一个列表,而parse (x:xs)返回一个裸号。

你可以使它工作,例如,通过在单个列表中返回数字

parse [] = []
parse (x:xs) = case x of
    Number y -> [y]

或通过返回空列表案例的数字

parse [] = 0
parse (x:xs) = case x of
    Number y -> y

或以其他多种方式,取决于您想要达到的目标。

答案 2 :(得分:1)

问题是你的第二个parse函数在传递空列表时返回List并且在传递非空Int时尝试返回List }。这就是编译器所抱怨的。

当您使用案例或模式匹配时,最好编写所有可能的构造函数。想想当有人使用parse调用时,[Otherthings, Number 3]函数会发生什么。

您应该使用Maybe代替并匹配Data type的所有构造函数:

parse []     = Nothing
parse (x:xs) = case x of
    Number y    -> Just y
    Otherthings -> Nothing

答案 3 :(得分:0)

你已经拥有

parse x = case x of
    Number y -> y

你想拥有parseList,它看起来像:

parseList = map parse

或以更详细的方式撰写:

parseList [] = []
parseList (x:xs) = parse x : parseList xs

parseList [] = []
parseList (x:xs) = case x of
    Number y -> y : parseList xs

也许你忘了解析rest元素,只解析第一个