Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 非穷举模式错误haskell_String_Haskell_Matching - Fatal编程技术网

String 非穷举模式错误haskell

String 非穷举模式错误haskell,string,haskell,matching,String,Haskell,Matching,我正在尝试将用户输入解析为我的数据类型: type Var = String data FProp = V Var | No FProp | Y FProp FProp | O FProp FProp | Si FProp FProp | Sii FProp FProp deriving Read 使用此功能,通过模式匹配: f:: [String] -> FProp

我正在尝试将用户输入解析为我的数据类型:

type Var = String
data FProp = V Var
            | No FProp
            | Y FProp FProp
            | O FProp FProp
            | Si FProp FProp
            | Sii FProp FProp deriving Read
使用此功能,通过模式匹配:

f:: [String] -> FProp
f("(":"S":"i":"(":xs) = (Si (let x = fst (span (/= ")") xs) in f x) (let y = snd (span (/= ")") xs) in f y))
f("(":"Y":"(":xs) = (Y (let x = fst (span (/= ")") xs) in f x) (let y = snd (span (/= ")") xs) in f y))
f("(":"S":"i":"i":"(":xs) = (Sii (let x = fst (span (/= ")") xs) in f x) (let y = snd (span (/= ")") xs) in f y))
f("(":"O":"(":xs) = (O (let x = fst (span (/= ")") xs) in f x) (let y = snd (span (/= ")") xs) in f y))
f("(":"N":"O":"(":xs) = (No (f xs))
f ("(":"V":"(":xs) = (V(head xs))
输入看起来像:“(Si(V(q))(No(V(p)))”(相当于公式:q->p)

当我遇到这个错误时,似乎一切都很顺利:函数f中的非穷举模式 我能得到一些帮助来解决这个问题吗?
我认为这可能与我定义最后一个递归案例(V的案例)的方式有关。

您实现的函数是部分的,并不是所有案例都包含在内。您需要添加一个catch all case并返回一个错误。 要做到这一点,函数应该返回一个允许建模解析失败的类型(如
Error FProp


在我看来,您可以使用创建一个更好的解析器。您可能还需要调查许多情况。

您实现的功能是部分的,并非所有情况都包括在内。您需要添加一个catch all case并返回一个错误。 要做到这一点,函数应该返回一个允许建模解析失败的类型(如
Error FProp


在我看来,您可以使用创建一个更好的解析器。您可能还需要调查许多问题。

您可以使用
-Wall
进行编译,它将显示缺少哪些模式,但也就是说,您使此函数非常复杂。我建议使用下推自动机,以列表(作为堆栈)作为累加器。此外,这并不总是有效,因为
span(/=”)
从找到结束括号的那一刻起就会被切断,但是如果你写
“foo(bar(qux))”
,那么它就会找到
bar(qux
作为内部内容。你能更具体地说明acumulator的想法吗?我实际上对如何实现它有点迷茫。你可以将堆栈实现为列表,其中列表的头是堆栈的顶部。你可以使用
cons
推送,然后使用
head
弹出。或者你可以编写递归下降解析器并使用内置的stack、 但是你似乎在这项任务的一部分中遇到了很多问题,而这部分是你应该学习的要点的辅助部分。你可能会发现稍后手工编写解析器是很有价值的,但也许你想在这里采取简单的方法。你可以用
-Wall
编译,它将显示哪些模式缺少,但也就是说,您使此函数非常复杂。我建议使用下推自动机,以列表(作为堆栈)作为累加器。此外,由于
span(/=”)
将从找到结束括号的那一刻起切断,因此这并不总是有效。但是如果您编写
“foo(bar(qux))”
,然后它将找到
条(qux
作为内部内容。你能更具体地说明acumulator的想法吗?我实际上对如何实现它有点迷茫。你可以将堆栈实现为列表,其中列表的头是堆栈的顶部。你可以使用
cons
推送,然后使用
head
弹出。或者你可以编写递归下降解析器并使用内置的stack、 但是你似乎对这项任务的一部分有很多问题,而这部分是你应该学习的要点的辅助部分。你可能会发现稍后手工编写解析器是很有价值的,但也许你想简单一点。问题是,我不能使用parsec库,因为我只是我们要使用前奏功能。好的,我明白了,我可以推荐这个吗?Error=String
f::[String]->Error FProp
..
f\uz=Left“无法识别的表达式”
问题是,我不能使用parsec库,因为我只能使用prelude函数。我明白了,我可以推荐这个吗?Error=String
f::[String]->Error FProp
..
f\uz=Left“unrecogned expression”