I am learning Haskell and was doing a simple DB-seed program for Yesod when I stumbled upon this behavior which I find hard to understand:
testFn :: Int -> Bool -> [Int] testFn a b = if b then replicate 10 a else 
欧洲杯买球Yesod GHCI session:
$ :t concatMap testFn  concatMap testFn  :: Bool -> [Int] $ (concatMap testFn [1,2,3]) True [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3]
Somehow it was able to "pull" out that second "Bool" from each of mappings into a single curried argument.
欧洲杯买球Standard base Prelude GHCI session refuses to even compile this expression:
$ :t concatMap testFn  error: • Couldn't match type 'Bool -> [Int]' with '[b]' Expected type: Int -> [b] Actual type: Int -> Bool -> [Int] • Probable cause: 'testFn' is applied to too few arguments In the first argument of 'concatMap', namely 'testFn' In the expression: concatMap testFn 
Turns out Yesod uses library which has its own
$ :t concatMap concatMap :: (MonoFoldable mono, Monoid m) => (Element mono -> m) -> mono -> m
At my current level of Haskell understanding I couldn't figure out how types are distributed here. Could someone explain to me (as much beginner oriented as possible) how this trick is done? What part of
testFn above is conforming to
Element mono type?