[Haskell] Mixing monadic and non-monadic functions
Keean Schupke
k.schupke at imperial.ac.uk
Thu Sep 8 04:34:33 EDT 2005
Can't you do automatic lifting with a "Runnable" class:
class Runnable x y where
run :: x -> y
instance Runnable (m a) (m a) where
run = id
instance Runnable (s -> m a) (s -> m a) where
run = id
instance (Monad m,Monad n,MonadT t m,Runnable (m a) (n a)) =>
Runnable (t m a) (n a) where
run = run . down
instance (Monad m,MonadT t m,Monad (t m)) => Runnable (t m a) (m a)
where
run = down
Where:
class (Monad m,Monad (t m)) => MonadT t m where
up :: m a -> t m a
down :: t m a -> m a
For example for StateT:
downST :: Monad m => StateT st m a -> (st -> m a)
downST m = \st -> do
(_,a) <- runST m st
return a
downST' :: Monad m => (b -> StateT st m a) -> (st -> b -> m a)
downST' m = \st b -> do
(_,a) <- runST (m b) st
return a
instance (MonadState st (StateT st m),Monad m,Monad n,Runnable (st
-> m s) (st -> n s)) => Runnable (StateT st m s) (st -> n s)
where
run = run . downST
instance (MonadState st (StateT st m),Monad m) => Runnable (StateT
st m s) (st -> m s) where
run = downST
Keean.
Frederik Eaton wrote:
>Hi,
>
>Sean's comment (yeah, it was like a billion years ago, just catching
>up) is something that I've often thought myself.
>
>I want the type system to be able to do "automatic lifting" of monads,
>i.e., since [] is a monad, I should be able to write the following:
>
>[1,2]+[3,4]
>
>and have it interpreted as "do {a<-[1,2]; b<-[3,4]; return (a+b)}".
>
>Also, I would have
>
>Reader (+1) + Reader (+4) == Reader (\x -> 2*x+5)
>
>The point I want to make is that this is much more general than IO or
>monads! I think we all understand intuitively what mathematicians mean
>when they add two sets
>
>{1,2}+{3,4} (i.e. { x+y | x\in {1,2}, y\in {3,4}})
>
>or when they add functions
>
>(f+g)(x) where f(x)=x+1 and g(x)=x+4
>
>So "automatic lifting" is a feature which is very simple to describe,
>but which gives both of these notations their intuitive mathematical
>meaning - not to mention making monadic code much tidier (who wants to
>spend their time naming variables which are only used once?). I think
>it deserves more attention.
>
>I agree that in its simplest incarnation, there is some ugliness: the
>order in which the values in the arguments are extracted from their
>monads could be said to be arbitrary. Personally, I do not think that
>this in itself is a reason to reject the concept. Because of currying,
>the order of function arguments is already important in Haskell. If
>you think of the proposed operation not as lifting, but as inserting
>`ap`s:
>
>return f `ap` x1 `ap` ... `ap` xn
>
>then the ordering problem doesn't seem like such a big deal. I mean,
>what other order does one expect, than one in which the arguments are
>read in the same order that 'f' is applied to them?
>
>Although it is true that in most of the instances where this feature
>would be used, the order in which arguments are read from their monads
>will not matter; yet that does not change the fact that in cases where
>order *does* matter it's pretty damn easy to figure out what it will
>be. For instance, in
>
>print ("a: " ++ readLn ++ "\nb: " ++ readLn)
>
>two lines are read and then printed. Does anybody for a moment
>question what order the lines should be read in?
>
>Frederik
>
>
>
>On Tue, Mar 23, 2004 at 12:55:56PM -0500, Sean E. Russell wrote:
>
>
>>On Tuesday 23 March 2004 11:36, Graham Klyne wrote:
>>
>>
>>>I think you're a rather stuck with the "temporary variables" (which they're
>>>not really), but it might be possible to hide some of the untidiness in an
>>>auxiliary monadic function.
>>>
>>>
>>That seems to be the common suggestion: write my own visitors.
>>
>>I'm just surprised that there isn't a more elegant mechanism for getting
>>interoperability between monadic and non-monadic functions. The current
>>state of affairs just seems awkward.
>>
>>[Warning: quasi-rant]
>>
>>Caveat: I'm not smart enough, and I don't know enough, to criticize Haskell,
>>so please don't misconstrue my comments. To quote Einstein: "When I'm asking
>>simple questions and I'm getting simple answers, I'm talking to God." I
>>simply mistrust, and therefore question, systems where simple things are
>>overly involved.
>>
>>The standard explaination about why monads are so troublesome always sounds
>>like an excuse to me. We have monads, because they allow side-effects. Ok.
>>If programs that used side effects were uncommon, I'd be fine with them being
>>troublesome -- but they aren't. Maybe it is just me, but my Haskell programs
>>invariably develop a need for side effects within a few tens of lines of
>>code, whether IO, Maybe, or whatnot. And I can't help but think that
>>language support to make dealing with monads easier -- that is, to integrate
>>monads with the rest of the language, so as to alleviate the need for
>>constant lifting -- would be a Good Thing.
>>
>>Hmmm. Could I say that Haskell requires "heavy lifting"?
>>
>>--
>>### SER
>>### Deutsch|Esperanto|Francaise|Linux|XML|Java|Ruby|Aikido
>>### http://www.germane-software.com/~ser jabber.com:ser ICQ:83578737
>>### GPG: http://www.germane-software.com/~ser/Security/ser_public.gpg
>>
>>
>
>
>
>
>
>>_______________________________________________
>>Haskell mailing list
>>Haskell at haskell.org
>>http://www.haskell.org/mailman/listinfo/haskell
>>
>>
>
>
>
>
More information about the Haskell
mailing list