之前我在与此项目相关的问题中获得了一些非常有用的提示,但现在,我需要以下方面的帮助。我有一个数据类型(与上一个问题相同):
type Var = String
data FProp = V Var
| No FProp
| Y FProp FProp
| O FProp FProp
| Si FProp FProp
| Sii FProp FProp
deriving Read
我需要将用户的输入字符串解析为我的数据类型。我终于建立了这个功能:
main = do
putStrLn "Welcome! Choose your option."
a <- getLine
if (a Prelude.== "(1)")
then do
y <- getLine
let ys = read (y)::String
in let f = parseStringToFProp ys
in let b = determinarTautologia f
in printResult b
else do
y <- getLine
x <- getLine
let {ys = read (y)::String; xs = read (x)::String}
in let {f1 = parseStringToFProp ys; f2 = parseStringToFProp xs}
in let b = sonEquivalentes f1 f2
in printResult b
这是调用解析器的函数的代码,这是我的主要疑问:
f:: [Char] -> FProp
f (x:xs) | x == ' '= f xs
| x == '(' || x == ')' = f xs
| x == 'S' && head xs Prelude.== 'i'
&& head (tail xs) == 'i' = (Sii (f xs))
| x == 'S' && head xs == 'i'
&& not (head (tail xs) == 'i') = (Si (f xs))
| x == 'Y' = (Y (f xs))
| x == 'O' = (O (f xs))
| x == 'N' && head xs == 'o' = (O (f xs))
该函数旨在从String创建FProp,其类型为[Char] -> FProp
。问题是我没有提出这个递归函数的基本情况。如果我[]
,我该怎么办?
答案 0 :(得分:0)
使用read函数,您不再需要解析,只需在输入中编写数据类型,就像之前在数据构造函数中声明的那样,即使是括号,例如:No (V “some string”)
答案 1 :(得分:0)
如果您可以自由选择任何输入格式,并且用户可以输入以下表达式:
(Si (V "q") (No (V "p")))
引号和所有,然后有一个非常简单的解决方案。
您可以通过在定义的末尾添加Read
,让Haskell为您的数据类型派生deriving (Read)
个实例。您已经完成了此操作,但您可能还没有意识到这样做的效果是自动为您的数据类型定义解析器,可以通过read
使用{{1和一些相关的函数。
例如,如果您编译并运行以下独立程序:
reads
这会自动将用户提供的字符串解析为type Var = String
data FProp = V Var
| No FProp
| Y FProp FProp
| O FProp FProp
| Si FProp FProp
| Sii FProp FProp
deriving (Show, Read)
main :: IO ()
main = do
putStrLn "Enter an expression:"
str <- getLine
let fprop = read str :: FProp
putStrLn "Your expression was:"
print fprop
(只需将其打印出来,但您可以在真实程序中使用FProp
执行任何操作):
fprop
这个程序不是很强大。如果输入无效表达式,则会生成异常。您可以使用$ runghc Proposition.hs
Enter an expression:
(Si (V "q") (No (V "p")))
Your expression was:
Si (V "q") (No (V "p"))
$
来使其更加用户友好:
reads