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:

class="lang-hs prettyprint-override">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:

class="lang-hs prettyprint-override">foldmapm helper'' (partitions (n - 1))

assuming that: helper'' :: int -> myreader (set int)

this of course of study require foldmapm function signature similar to:

class="lang-hs prettyprint-override">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

Popular posts from this blog

php - Edges appear in image after resizing -

ios8 - iOS custom keyboard - preserve state between appearances -

Delphi change the assembly code of a running process -