接受两个monadic值并返回单个monadic值的通用函数

Naw*_*waz 3 generics monads haskell scala

我编写了下面的Haskell函数,它接受两个monadic值并将它们组合成一个monadic值(它只是为了说明Haskell类型系统可以支持的通用性(或泛型)的程度).

combine x y = do
  a <- x
  b <- y
  return (a, b)
Run Code Online (Sandbox Code Playgroud)

我用三种不同的单子测试了它:

main = do
  putStrLn $ show $ combine (Just 10) (Just 20)  -- Maybe a
  putStrLn $ show $ combine [100] [10, 20]       -- [] a
  a <- combine getLine getLine                   -- IO a
  putStrLn $ show a
Run Code Online (Sandbox Code Playgroud)

它按预期工作得很好.现在,我想知道Scala的类型系统是否允许我在不影响通用性的情况下编写上述函数.但我不太了解斯卡拉(虽然我希望探索它).那么有人可以帮助我将此代码转换为Scala吗?

Joe*_*las 7

我认为这相当于:

import cats._
import cats.implicits._

def combine[T, F[_]: Monad](fa: F[T], fb: F[T]) = for {
    a <- fa
    b <- fb
  } yield (a, b)
Run Code Online (Sandbox Code Playgroud)

Monad从库(猫或scalaz).

combine(Option(10), Option(20))生产Some((10,20))combine(List(100), List(10, 20))生产List((100,10), (100,20)).

编辑:以上版本过度约束,因为它要求两个参数类型相同. def combine[A, B, F[_]: Monad](fa: F[A], fb: F[B])解决了这个问题.