【问题标题】:Make function return different types haskell使函数返回不同类型的haskell
【发布时间】:2021-12-01 06:23:53
【问题描述】:

我对 haskell 完全陌生。我需要一个返回运算符或以字符串形式返回错误消息的函数。对于上下文,我正在构建一个接受双精度的 Monadic Parser。

term'::Parser Double
term' = factor' `chainl1` mulop

addop, mulop :: Parser (Double -> Double -> Double)
mulop = do symbol "^" 
           return (**)
        +++ do symbol "*" 
               return (*)
        +++ do symbol "/"
               return (/)

addop = do symbol "+" 
           return (+)
        +++ do symbol "-"
               return (-)

上面的代码可以很好地返回运算符,但是当我尝试通过添加错误消息来扩展它时,我得到了编译错误。以下是我正在尝试的。

mulop :: Either (Parser (Double -> Double -> Double)) (Parser String)
mulop = do symbol "^" 
            return Left (**)
        +++ do symbol "*" 
               return Left (*)
        +++ do symbol "/" 
               return Left (/)
        +++ pure Right "ERROR MSG"

【问题讨论】:

  • return Left (**) 应该是return (Left (**))(或return $ Left (**))。否则你用两个单独的参数调用returnLeft(**),这是没有意义的。
  • 为什么不打电话给fail "ERROR MSG"
  • 思路是按照上述方式处理,不引发异常

标签: parsing haskell monads


【解决方案1】:

这只是一个解析器。它需要输入来决定输出是运算符还是错误字符串。所以签名必须是

mulop :: Parser (Either (Double -> Double -> Double) String)

实际上有一个约定,当使用Either作为添加异常的类型时,错误消息应该在Left上,所以也许更好

mulop :: Parser (Either String (Double -> Double -> Double))

在实现中:注意语法规则的正确性。 returnpure 只是普通函数,而不是像过程语言中的 return 这样的特殊关键字。所以必须是return $ Left (**)

还要确保缩进正确。我会这样调整:

mulop = do symbol "^" 
           return $ Right (**)
    +++ do symbol "*" 
           return $ Right (*)
    +++ do symbol "/" 
           return $ Right (/)
    +++ pure (Left "ERROR MSG")

或者,不要使用do 表示法。你真的不需要任何单子,你可以使用<$ operator

mulop = (Right (**) <$ symbol "^")
    +++ (Right (*) <$ symbol "*")
    +++ (Right (/) <$ symbol "/")
    +++ pure (Left "ERROR MSG")

【讨论】:

  • 非常感谢,它运行良好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
相关资源
最近更新 更多