Я работаю через learning scalaz и Learn You A Haskell For Greater Good и задаюсь вопросом, как перевести пример filterM из LYAHFGG в Scala.Scalaz Writer Monad and filterM
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)
^
Вторая вещь, спасибо! Первый не компилируется - попытался это исправить, но мои знания слишком ограничены. Вот обратный вопрос: http://stackoverflow.com/questions/8736164/what-are-type-lambdas-in-scala-and-what-are-their-benefits Я думаю, быть доступным и в Haskell, но не в конкретном примере Writer, не так ли? http://stackoverflow.com/questions/4069840/lambda-for-type-expressions-in-haskell – mjaskowski
Я мало знаю о том, как Haskell справляется с этим, но я подозреваю, что он немного более гибкий, когда частично применяя типы с несколькими параметрами. Я хотел бы знать, что такое отказ для типа лямбда. –