很高兴(至少在Safe Haskell中)从签名中知道某些东西是否执行IO操作,但IO包含许多不同的东西- putStr
、数据库访问、删除和写入文件、IORefs等。
如果我在运行任意代码时使用类型签名作为安全措施,情况可能是我愿意接受一些IO操作-例如putStr
和类似的操作-但不接受其他操作。
有没有办法定义一个受限版本的IO monad,只包含普通IO操作的一个子集?如果是这样的话,一个例子(比如putStr
)将会非常受欢迎!
发布于 2013-12-02 09:52:39
作为我的评论的后续内容,您可以自己实现它,如下所示
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
类结合。如果您有多个类,比如定义了getLine_
、getChar_
等的Stdin
类,您甚至可以将这些类型类与
class (Stdout io, Stdin io) => StdOutIn io where
myFunc :: StdOutIn io => io ()
myFunc = do
val <- getLine_
putStrLn_ $ "Echo: " ++ val
main :: IO ()
main = myFunc
https://stackoverflow.com/questions/20318936
复制相似问题