【问题标题】:Structuring a Haskell program构建 Haskell 程序
【发布时间】:2016-08-10 07:32:45
【问题描述】:

我正在尽我所能构建一个 haskell 模块,这就是我想出的。

输入可以是 Fix 或 Twitter 解析器的输出可能是输出,我想将解析器的输出标记为结构化或非结构化。

这是正确的类型签名吗?我是否正确使用了可能的单子实例类?这是在haskell中处理副作用的正确方法吗?

module Parsers.Parser(
      handle
    ) where

data Input = FIX Text
        | Twitter Text

data Output = StructuredDataEvent Quote 
            | UnStructuredDataEvent  Text

handle :: Input -> Output
handle (FIX r)      = fixParser  r >>=   StructuredDataEvent  
handle (Twitter r)  = twitterParser  r >>=  UnStructuredDataEvent

sideEffects:: Output -> Output
sideEffects   a = LogEventToDatabase a

instance Monad Maybe where  
    return x = Just $ sideEffects x  
    Nothing >>= f = Nothing  
    Just x >>= f  = f $ sideEffects x  
    fail _ =  Nothing  

【问题讨论】:

  • Maybe 已经是Monad 的一个实例。通常也不清楚您在说什么。这段代码能编译吗?
  • 如果这是编译和工作,我将不太倾向于堆栈溢出......这可能不是标准的单子......我正在将内容记录到数据库中返回 x = 只是 $ sideEffects x Just x >>= f = f $ sideEffects x 我的问题是这是否是处理副作用的正确方法并且因为 >>= 不能返回任何内容是:handle :: Input -> Output 或 handle :: Input -> Maybe Output正确的签名
  • LogEventToDatabase 是做什么的?这可能没有通过单子定律。回答您的问题:不,这不是在 Haskell 中处理副作用的正确方法。
  • (LogEventToDatabase a) 将“a”的内容插入数据库并返回a。
  • @Devitect 它在 IO 之外执行此操作?

标签: haskell


【解决方案1】:

如果你真的想做副作用,handle 应该是 Input -> IO Output 类型。

但最好编写一个纯解析器来保存所有错误消息的列表。如果他们只是Strings,例如using the Writer monad

handle :: Input -> Writer [String] Output

另外,你考虑过using Parsec,它是monad转换器吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多