【问题标题】:Scalaz Writer Monad and filterMScalaz Writer Monad 和 filterM
【发布时间】:2015-09-21 10:23:40
【问题描述】:

我正在研究learning scalazLearn You A Haskell For Greater Good,想知道如何将 filterM 示例从 LYAHFGG 转换为 Scala。

fst $ runWriter $ filterM keepSmall [9,1,5,2,10,3]

keepSmall 定义为

keepSmall :: Int -> Writer [String] Bool  
keepSmall x  
    | x < 4 = do  
        tell ["Keeping " ++ show x]  
        return True  
    | otherwise = do  
        tell [show x ++ " is too large, throwing it away"]  
        return False

我的天真方法以编译错误结束,我不知道如何解决这个问题!

    val keepSmall: (Int => WriterT[Id, Vector[String], Boolean]) = (x: Int) => 
      if (x < 4) for {
        _ <- Vector("Keeping " + x.shows).tell
      } yield true
      else for {
        _ <- Vector(x.shows + " is too large, throwing it away").tell
      } yield false

println(List(9,1,5,2,10,3) filterM keepSmall)

编译错误:

 Error:(182, 32) no type parameters for method filterM: (p: Int => M[Boolean])(implicit evidence$4: scalaz.Applicative[M])M[List[Int]] exist so that it can be applied to arguments (Int => scalaz.WriterT[scalaz.Scalaz.Id,Vector[String],Boolean])
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Int => scalaz.WriterT[scalaz.Scalaz.Id,Vector[String],Boolean]
 required: Int => ?M[Boolean]
    println(List(9,1,5,2,10,3) filterM keepSmall)
                               ^

Error:(182, 40) type mismatch;
 found   : Int => scalaz.WriterT[scalaz.Scalaz.Id,Vector[String],Boolean]
 required: Int => M[Boolean]
    println(List(9,1,5,2,10,3) filterM keepSmall)
                                       ^

【问题讨论】:

    标签: scala haskell scalaz scalaz7


    【解决方案1】:

    问题是由于 Scala 无法真正知道如何将具有三个 holes 的类型拟合到 filterM 预期的参数中,该参数只有一个 hole 用Boolean 填充。

    你可以使用一些奇怪的 type-lambda 语法来解决你的问题(未经测试,可能不起作用):

    val keepSmall: (Int => ({type L[T] = WriterT[Id, Vector[String], T]})#L) = ...
    

    或者(更容易)引入一个类型别名,如下所示:

    type MyWriter[T] = WriterT[Id, Vector[String], T]
    val keepSmall: (Int => MyWriter[Boolean]) = ...
    

    这将确保filterM 期望的参数类型与您提供的参数类型相匹配。

    【讨论】:

    • 第二个做的事情,谢谢!第一个没有编译 - 试图以某种方式修复它,但我的知识太有限了。这是我的一个相反的问题:stackoverflow.com/questions/8736164/… 我想类似的东西必须在 Haskell 中也可用,但在 Writer 的特定示例中不可用,对吧? stackoverflow.com/questions/4069840/…
    • 我不太了解 Haskell 如何处理这个问题,但我怀疑在部分应用具有多个参数的类型时它会更灵活一些。我想知道 lambda 类型的失败是什么。
    猜你喜欢
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    相关资源
    最近更新 更多