我有以下代码:
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')
函数不会编译。我怎样才能做到这一点? 谢谢
答案 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' = ...