使用readMaybe测试输入

时间:2018-02-09 17:01:41

标签: haskell

我正在尝试为大学的项目开发一个计算器。 在项目中我可以使用它的内部存储器来执行操作。那就是问题所在。当它是一个String并且它是一个Float时,我无法分隔这些条目。如果它是一个字符串,我需要在内存中查找该字符串,如果它是一个浮点数,我需要从String转换为Float,然后在计算中使用。到目前为止我找到的解决方案是:

   'calculator :: Memory -> IO Memory
   'calculator mem = do
       x <- getLine
       let k = if isNothing (readMaybe (head (tail (words x))))
           then find mem (head (tail (words x)))
           else getVar1 x
           j = if isNothing (readMaybe (head (tail (words (x)))))
           then find mem (head (tail (tail (words x))))
           else getVar2 x'

我有一个记忆,它是[Conteudo]的类型,而Conteudo等于(String,Float)。 例如,当您使用计算器时,要添加5和9,则键入add 5 9 结果将打印在屏幕上,并将值保存在我的记忆位置(“ans”,14)。你有可能把另一个命令放到A.它会在内存的A位置存储ans例如:(“A”,14)的值。我的问题是我不能混合两个输入。例如,添加A 8。

打印此错误

Ambiguous type variable `a0' arising from a use of `readMaybe'
  prevents the constraint `(Read a0)' from being solved.
  Probable fix: use a type annotation to specify what `a0' should be.
  These potential instances exist:
    instance Read Lexeme -- Defined in `GHC.Read'
    instance Read Ordering -- Defined in `GHC.Read'
    instance Read Integer -- Defined in `GHC.Read'
    ...plus 23 others
    ...plus six instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the first argument of `isNothing', namely
    `(readMaybe (head (tail (tail (words x)))))'
  In the expression:
    isNothing (readMaybe (head (tail (tail (words x)))))
  In the expression:
    if isNothing (readMaybe (head (tail (tail (words x))))) then
        find mem (head (tail (tail (words x))))
    else
        getVar2 x

如果有人可以帮助我,谢谢你

1 个答案:

答案 0 :(得分:1)

您收到的错误消息是因为您没有告诉GHC它应该读取字符串的类型。与GHCI相比:

Prelude> read "3.2"
*** Exception: Prelude.read: no parse
Prelude> read "3.2" :: Float
3.2

然而,更好的解决方案是制作包含两种可能性的产品类型,以及可以将这两种情况评估为Num的函数。

data Term = Name  String
          | Value Float

eval :: Memory -> Term -> Float
eval _   (Value n) = n
eval mem (Name  s) = find mem s  -- presumably?
                                 -- though this should probably give a Maybe Float

然后您可以使用readMaybe来实现解析器。

parseTerm :: String -> Term
parseTerm s = case (readMaybe s :: Maybe Float) of
              Just v  -> Value v
              Nothing -> Name  s