划分IO monad [英] Delimiting the IO monad

查看:139
本文介绍了划分IO monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很高兴知道(至少在Safe Haskell中)签名是否有东西执行IO操作,但IO包含很多不同的东西 - putStr ,数据库访问,删除和写入文件,IORefs等。

It's nice to know (in Safe Haskell, at least) from the signature whether or not something performs IO actions, but IO encompasses a lot of different things - putStr, database access, removing and writing to files, IORefs, etc.

如果我在运行任意代码时使用类型签名作为安全措施,可能就是这种情况我愿意接受一些IO动作 - 例如 putStr 等等 - 而不是其他人。

If I'm using the type signatures as a security measure when running arbitrary code, it might be the case that I'm willing to accept some IO actions - putStr and the ilk, for instance - but not others.

有没有办法定义IO monad的受限版本,只有一部分正常的IO操作?如果是这样,一个例子(例如 putStr )将是非常受欢迎的!

Is there a way to define a restricted version of the IO monad, with only a subset of the normal IO actions? If so, an example (with putStr, for instance) would be very welcome!

推荐答案

作为我评论的后续内容,你可以自己实现它,比如

As a follow up to my comment, you can implement it yourself with something like

class Monad io => Stdout io where
    putStr_ :: String -> io ()
    putStrLn_ :: String -> io ()
    print_ :: Show a => a -> io ()
    -- etc

instance Stdout IO where
    putStr_ = putStr
    putStrLn_ putStrLn
    print_ = print

myFunc :: Stdout io => io ()
myFunc = do
    val <- someAction
    print_ val
    let newVal = doSomething val
    print_ newVal

main :: IO ()
main = myFunc

这绝对没有运行时开销,因为GHC将优化那些类型类仅使用 IO monad,它可扩展,易于编写,并且可以与monad变换和 MonadIO结合使用很容易上课。如果您有多个类,例如 Stdin 类,其中 getLine _ getChar _ 等,您甚至可以将这些类型组合与

This will have absolutely no runtime overhead, since GHC will optimize away those typeclasses to use only the IO monad, it's extensible, easy to write, and can be combined with monad transformes and the MonadIO class quite easily. If you have multiple class, such as a Stdin class with getLine_, getChar_, etc defined, you can even combine these typeclasses with

class (Stdout io, Stdin io) => StdOutIn io where

myFunc :: StdOutIn io => io ()
myFunc = do
    val <- getLine_
    putStrLn_ $ "Echo: " ++ val

main :: IO ()
main = myFunc

这篇关于划分IO monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆