我最近看了一個關於如何提出IO monad的視頻,談話是在scala中。我實際上想知道具有函數返回IO [A]的點是什麼。包裝在IO對象中的lambda表達式就是突變,在某種程度上它們必須被觀察到更高的變化,我的意思是執行,以便發生某些事情。你不只是把問題推到別的地方嗎?Scala IO monad:有什麼意義?
我可以看到的唯一好處是它允許延遲評估,因爲如果您不調用unsafePerformIO操作,則不會發生副作用。此外,我猜想該程序的其他部分可以使用/共享代碼並在需要發生副作用時分離。
我想知道這是否全部?可測試性有沒有優勢?我假設不是你必須觀察到否定這種否定的效果。如果你使用特質/接口,你可以控制依賴關係,但不能在這些依賴關係發生效果時進行控制。
我把下面的例子放在代碼中。
case class IO[+A](val ra:() => A){
def unsafePerformIO() : A = ra();
def map[B](f: A => B) : IO[B] = IO[B](() => f(unsafePerformIO()))
def flatMap[B](f: A => IO[B]) : IO[B] = {
IO(() => f(ra()).unsafePerformIO())
}
}
case class Person(age: Int, name: String)
object Runner {
def getOlderPerson(p1: Person,p2:Person) : Person =
if(p1.age > p2.age)
p1
else
p2
def printOlder(p1: Person, p2: Person): IO[Unit] = {
IO(() => println(getOlderPerson(p1,p2))).map(x => println("Next"))
}
def printPerson(p:Person) = IO(() => {
println(p)
p
})
def main(args: Array[String]): Unit = {
val result = printPerson(Person(31,"Blair")).flatMap(a => printPerson(Person(23,"Tom"))
.flatMap(b => printOlder(a,b)))
result.unsafePerformIO()
}
}
你可以看到效果是如何延遲到主要我認爲是很酷的。我從視頻中瞭解到這一點後就提出了這個問題。
我的執行是否正確,我的理解是否正確。
我也想知道是否應該將它與ValidationMonad結合起來,就像在ValidationMonad [IO [Person]]中一樣,這樣當異常發生時我們可以短路。請思考。
布萊爾
謝謝。很好的答案我今晚會看看這些想法。 –
你有沒有帶子類和類型類的代碼片段? –
查看Drexin鏈接到的Runar的幻燈片,特別是'ConsoleIO'的東西。它演示瞭如果您運行這些操作('隱式對象ConsoleEffect ..')定義可能發生什麼IO動作('case object GetLine ...','case class PutLine ...')的聲明的分離。 .')。但請注意,其中還有其他內容。它不是最基本的代碼,只能說明我所說的。 –