1

I am new to Haskell and I am trying to monads. I read about the liftM2 and I wanted to know if you could make it variadic.

user12596
  • 71
  • 2

1 Answers1

1

In general, you can't have variadic Haskell functions because functions that take different numbers of parameters have very different types.

However, there is a generalization to liftM2 using operators from Control.Applicative that may find interesting:

liftM2 f a b = f <$> a <*> b
liftM3 f a b c = f <$> a <*> b <*> c
liftM4 f a b c d = f <$> a <*> b <*> c <*> d

(Technically, this applies only if your Monad is also Applicative, but as of ghc 7.10, all Monads are Applicative)

etc. It's worth working through the types to figure out how those expressions work.

Daniel Martin
  • 23,083
  • 6
  • 50
  • 70
  • You must mean `liftM2`, `liftM3` and `liftM4`, rather. Also, the definitions you give are those of `liftA2`, `liftA3` and `liftA4`. See http://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Base.html#liftM2 – jub0bs Jul 16 '15 at 03:08
  • Right, I swapped the `M` around; the hazards of answering from a mobile device. But as for the difference between `liftA2` etc and `liftM2`, that's what I meant by the comment about ghc 7.10. After the implementation of AMP, all properly defined Monads have `liftM2` defined to be identical to `liftA2`, etc. – Daniel Martin Jul 16 '15 at 19:12
  • Despite the AMP taking effect, the `liftMn` function are still implemented in monadic terms in `base`; see https://github.com/ghc/ghc/blob/b98ca17e12c7efdc906f4901f25e6263a5399be1/libraries/base/GHC/Base.hs#L566 – jub0bs Jul 16 '15 at 22:20
  • Sure, they are. So? The AMP requires that in a properly defined Monad `(<*>)` is identical to `ap`, and `fmap` to `liftM`, and the definitions you cite are equivalent to ``liftM2 f a b = f `liftM` a `ap` b``, ``liftM3 f a b c = f `liftM` a `ap` b `ap` c``, etc. – Daniel Martin Jul 17 '15 at 02:38