Lifting a function with another function as an argument in Haskell -
Lifting a function with another function as an argument in Haskell -
so have function in haskell i've simplified purpose of asking question:
class="lang-hs prettyprint-override">import data.foldable import data.set myfn :: int -> set int myfn | <= 0 = singleton 1 | otherwise = foldmap helper (myfn (a - 1)) helper :: int -> set int helper = insert (a + 2) (singleton a) main :: io () main = print . data.set.tolist $ myfn 5 i want have myfn's dependency on helper set reader, since inversion of command allows me switch implementations in tests:
import control.monad.reader import data.foldable import data.set info myenv = myenv { helper' :: int -> set int } type myreader = reader myenv myfn :: int -> myreader (set int) myfn | <= 0 = homecoming $ singleton 1 | otherwise = myfn' <- myfn (a - 1) helper'' <- asks helper' homecoming (foldmap helper'' myfn') helper :: int -> set int helper = insert (a + 2) (singleton a) main :: io () main = allow myenv = myenv helper in print . data.set.tolist $ runreader (myfn 5) myenv this works fine, except don't these 3 lines in particular:
class="lang-hs prettyprint-override">myfn' <- myfn (a - 1) helper'' <- asks helper' homecoming (foldmap helper'' myfn') i sense there should way lift foldmap in same way mapm lifted version of map through composition sequence. ideally, 3 lines collapse downwards one:
foldmapm helper'' (partitions (n - 1)) assuming that: helper'' :: int -> myreader (set int)
this of course of study require foldmapm function signature similar to:
foldmapm :: (monad m, foldable t, monoid n) => (a -> m n) -> m (t a) -> m n i have tried many things, cannot seem implement function, though! can help?
basically, create monad m => m -> m b -> m c a -> b -> c. that's liftm2 (from control.monad) does:
liftm2 :: monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r promote function monad, scanning monadic arguments left right. example,
liftm2 (+) [0,1] [0,2] = [0,2,1,3] liftm2 (+) (just 1) nil = nil therefore, it's simple using liftm2 foldmap:
myfn :: int -> myreader (set int) myfn | <= 0 = homecoming $ singleton 1 | otherwise = liftm2 foldmap (asks helper') (myfn (a - 1)) alternatively can utilize <$> , <*> control.applicative if don't additional parentheses:
myfn :: int -> myreader (set int) myfn | <= 0 = homecoming $ singleton 1 | otherwise = foldmap <$> asks helper' <*> myfn (a - 1) for more information, have @ typeclassopedia.
function haskell collections monads lifting
Comments
Post a Comment