Haskell variation binding

The following code is an attempt to write a variable function that acts as follows:

  • bind_variadic mx f = mx >>= f
  • bind_variadic mx my f = do { x <- mx; y <- my; fxy }

I can write it if you express the โ€œrest of the bindingโ€ as a variable k , but in order to write a class, I need to write one function in terms of another. To be precise, I want to express l1 in terms of l0 , l2 in terms of l1 , etc.

 import Prelude hiding ((>>=), (>>), Monad, return) -- override the default monad so we don't get confusing -- instances like "Monad (->)". class Monad m where (>>=) :: ma -> (a -> mb) -> mb (>>) :: ma -> mb -> mb return :: a -> ma fail :: String -> ma h :: Monad m => ma -> (t -> mb) -> (a -> t) -> mb h mx kf = mx >>= \x -> k (fx) l0 = h (return 3) id (\x -> return x) l1 = h (return 3) (h (return 4) id) (\xy -> return x) l2 = h (return 3) (h (return 4) (h (return 5) id)) (\xyz -> return x) 

Perhaps the solution includes another sequel?

change

here is an idea that requires an extra connection ...

 -- if not using Control.Monad, use this join :: Monad ๐”ช => ๐”ช (๐”ช ฮฑ) -> ๐”ช ฮฑ join mx = mx >>= id -- idea: get side effects of evaluating first arguments first h' mz kf = kf >>= \f' -> mz >>= (return . f') l1' = h' (return 3) return unary = join (l1' (\x -> return x)) l2' = h' (return 4) l1' binary = join (l2' (\xy -> return x)) l3' = h' (return 5) l2' ternary = join (l3' (\xyz -> return x)) 
+4
source share
1 answer

If you want to express it:

 ap_variadic mx f = mx >>= f ap_variadic mx my f = do { x <- mx; y <- my; fxy } 

Instead, I would use Control.Applicative . Then:

 join (f <$> mx) join (f <$> mx <*> my) join (f <$> mx <*> my <*> mz) 

I think this is better (simpler, more maintainable) than any multivariate solution.

+1
source

All Articles