3 ms·
How does a complete Haskell program using non-monadic IO look like? As for "most other Haskell monads", from what i can tell they're just wrappers around the c
by Mithaldu 13y ago
How does a complete Haskell program using non-monadic IO look like?
As for "most other Haskell monads", from what i can tell they're just wrappers around the core monads with additional functionality tacked on and i consider it lazy to also call them monads instead of wrappers.
- dllthomas 13y agoMost monads for which you can implement a monad transformer are implemented by wrapping the monad transformer around Identity, but that's simply because you would otherwise be implementing basically the same thing twice. My impression has been that they were originally implemented directly and only transformer-ified later. Certainly, there is no reason that couldn't have been done. Identity doesn't involve any particular voodoo: newtype Identity a = Identity { runIdentity :: a } instance Monad Identity where return a = Identity a m >>= k = k (runIdentity m) Haskell originally didn't include monadic IO - it was introduced in version 1.3, IIRC. IO looked like lazy streams of events, but it was pretty messy and pretty possible to deadlock, from what I hear. Writing modern Haskell, doing IO without any use of the IO type isn't possible, but you can - in principle - avoid ever using the fact that it's a monad by simply calling unsafePerformIO immediately on any IO action. Good luck actually ordering your IO operations, though.
- danidiaz 13y agoNot really, they are independent of IO (you may be thinking of monad transformers, which are ways to extend an existing monad.) For example, this is the entire definition of the Maybe monad: data Maybe a = Nothing | Just a deriving (Eq, Ord) instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just a) = Just (f a) instance Monad Maybe where (Just x) >>= k = k x Nothing >>= _ = Nothing (Just _) >> k = k Nothing >> _ = Nothing return = Just fail _ = Nothing It's just a way to propagate failure when sequencing computations. (That's why the "Nothings" are always followed with more "Nothings" in the definition.) This SO question describes Haskell's pre-monadic IO: http://stackoverflow.com/questions/17002119/haskell-pre-monadic-i-o http://stackoverflow.com/questions/17002119/haskell-pre-mona...
- dllthomas 13y agoA lot of monads in the mtl (State, Writer, Reader, &c) are implemented by applying their transformer to Identity. Your point stands, as that's not the only way to implement them, isn't the way many other monads are implemented, and Identity itself is implemented just in Haskell code, but it's a possible source of some of the confusion.
- Mithaldu 13y agoI'm beginning to see how my definition is wrong. Right now it seems to me like the simple definition of a Monad is: It's a prettied-up workaround. A bit i think i need to clarify: In my opinion most monad explanations fall entirely flat because they explain WHAT a monad does, but NEVER explain WHY they were created in the first place; making the whole exercise somewhat akin to mathematics teaching in us-american schools. With what all the responses pointed out it seems like monads get created when a pain point of a language is so often, and so consistently worked around in the same fashion; that someone decided to make an implementation of the workaround that looks like basic syntax; regardless of whether the implementation happens in core or in the language itself. Thus for example Moose, a library that bolts object orientation syntax onto Perl, would probably also be a monad. Am i still off-track?
- dllthomas 13y agoYou might be conflating monads with do-notation? Do-notation is a syntactic tweak to make using monads a little prettier, and is implemented in the language, but you can just as well use monads without it. Consider the IO example: main = getArgs >>= mapM_ putStrLn where getArgs :: IO [String] putStrLn :: String -> IO () mapM_ :: (a -> m b) -> [a] -> m ()
- tel 13y agoNope, definitely still off track. Typeclasses are a refactoring and abstraction tool used here, but monads are just an abstraction. They exist whether or not you reorganize your code. Even when you're using tuples and the like to implement state you still have a monad, you're just footing the bill on a bunch of complexity to implement it. This the same as how people talk about javascript and C as "having monads in their semicolons". Semicolons do behave much like monads. They're just not first-class nor officially recognized as such.