scala - Scalaz Writer Monad and filterM -
i working way through learning scalaz , learn haskell greater good , wonder how translate filterm example lyahfgg scala.
fst $ runwriter $ filterm keepsmall [9,1,5,2,10,3]
with keepsmall
defined as
keepsmall :: int -> writer [string] bool keepsmall x | x < 4 = tell ["keeping " ++ show x] return true | otherwise = tell [show x ++ " large, throwing away"] return false
my naive approach ends compilation errors , have no clue how go around issue!
val keepsmall: (int => writert[id, vector[string], boolean]) = (x: int) => if (x < 4) { _ <- vector("keeping " + x.shows).tell } yield true else { _ <- vector(x.shows + " large, throwing away").tell } yield false println(list(9,1,5,2,10,3) filterm keepsmall)
compilation errors:
error:(182, 32) no type parameters method filterm: (p: int => m[boolean])(implicit evidence$4: scalaz.applicative[m])m[list[int]] exist can applied arguments (int => scalaz.writert[scalaz.scalaz.id,vector[string],boolean]) --- because --- argument expression's type not compatible 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) ^
and
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) ^
the issue due fact scala can't know how fit type 3 holes argument expected filterm
, has 1 hole filled boolean
.
you solve problem using weird type-lambda syntax (not tested, may not work):
val keepsmall: (int => ({type l[t] = writert[id, vector[string], t]})#l) = ...
or (much easier) introducing type alias follows:
type mywriter[t] = writert[id, vector[string], t] val keepsmall: (int => mywriter[boolean]) = ...
this make sure kind of argument expected filterm
matches kind of argument providing.
Comments
Post a Comment