[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