I have the following code:

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')

when I try to run this I get a non-exhastive pattern error. I have tried changing the function to:

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')

the function wont compile. How can I do this? thank you

有帮助吗?

解决方案 2

The problem is that your function d_v_ds isn't taking in account lists with many elements but only the empty list [] and the list with one element [(v, xAexp)]. I think you misunderstood Haskell syntax because you are using tail [(v,xAexp)] to take the tail of a list of one element. I don't know what envV' and sto' are, but if I understood correctly what you want to do, that is working on each element of the list, your function can be rewritten:

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')

The match ((v,xAexp):xs) contains all you need: (v,xAexp) is the head of the list, xs is the tail of the list and (v,xAexp):xs says that you are waiting for a list composed by at least one element (xs can be empty).

其他提示

As the compiler says, your pattern matches are incomplete, meaning that in a sense all possible variations of the input are not captured.

Lets say we have the following function to be implemented:

aFunc :: [a] -> b

Consider the following pattern matches:

-- 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) = ...

Also, patterns are matched sequentially, so for easy design, generally make sure your set of pattern matches is mutually exhaustive, and keep your base case definition as the first one.

In your case, you should modify your function to something like:

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')

However, please note that envV' is not defined yet. And this function seems to only end up returning the second argument that you gave in the initial call.

Try this:

d_v_ds [] (envV, sto) = (envV, sto)
d_v_ds (_:rst) (envV, sto) = d_v_ds rst (envV', sto')
    where envV' = ...
          sto' = ...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top