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