选择haskell中元组列表的尾部

时间:2014-04-16 12:52:59

标签: haskell recursion tail

我有以下代码:

type DecV = [(Var,Aexp)]

d_v_ds :: DecV -> (EnvV, Store) -> (EnvV, Store)
d_v_ds [] (envV, sto) = (envV, sto)
d_v_ds [(v, xAexp)] (envV, sto) = do
                d_v_ds (tail ([(v, xAexp)])) (envV', sto')

当我尝试运行时,我得到一个非穷尽的模式错误。我尝试将功能更改为:

d_v_ds :: DecV -> (EnvV, Store) -> (EnvV, Store)
d_v_ds [] (envV, sto) = (envV, sto)
d_v_ds [(v, xAexp): a] (envV, sto) = do
                    d_v_ds (a) (envV', sto')

函数不会编译。我怎样才能做到这一点? 谢谢

3 个答案:

答案 0 :(得分:3)

正如编译器所说,您的模式匹配不完整,这意味着在某种意义上,不会捕获输入的所有可能变体。

假设我们要实施以下功能:

aFunc :: [a] -> b

考虑以下模式匹配:

-- Matches an empty list
aFunc [] = ...

-- Matches anything
aFunc x = ...

--Matches one member list
aFunc [x] = ...

-- Matches a two member list
aFunc [x,y] = ...

-- Matches a list with atleast one member
aFunc (x:xs) = ...

-- A mutually exhaustive set
aFunc [] = ...
aFunc (x:xs) = ...

此外,模式是按顺序匹配的,因此为了便于设计,通常要确保您的模式匹配集是相互详尽的,并将基本案例定义保留为第一个。

在您的情况下,您应该将您的功能修改为:

d_v_ds :: DecV -> (EnvV, Store) -> (EnvV, Store)
d_v_ds [] (envV, sto) = (envV, sto)
d_v_ds ((v, xAexp): xs ) (envV, sto) = d_v_ds xs (envV', sto')

但请注意,envV'尚未定义。而且这个函数似乎最终只返回你在初始调用中给出的第二个参数。

答案 1 :(得分:1)

问题在于,您的功能d_v_ds并未考虑包含多个元素的帐户列表,而只包含空列表[]和包含一个元素[(v, xAexp)]的列表。我认为您误解了Haskell语法,因为您使用tail [(v,xAexp)]来获取一个元素列表的尾部。 我不知道envV'sto'是什么,但如果我理解你想要做什么,那就是对列表的每个元素都有效,那么你的函数可以被重写:

d_v_ds :: DecV -> (EnvV, Store) -> (EnvV, Store)
d_v_ds []              (envV, sto) = (envV, sto)
d_v_ds ((v, xAexp):xs) (envV, sto) = d_v_ds xs (envV', sto')

匹配((v,xAexp):xs)包含您需要的所有内容:(v,xAexp)是列表的头部,xs是列表的尾部,(v,xAexp):xs表示您正在等待由至少一个元素(xs组成的列表可以为空)。

答案 2 :(得分:0)

试试这个:

d_v_ds [] (envV, sto) = (envV, sto)
d_v_ds (_:rst) (envV, sto) = d_v_ds rst (envV', sto')
    where envV' = ...
          sto' = ...