本文介绍了将Haskell monad直接翻译成Scala的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 试图学习如何在Scala中编写monad,遇到了一些麻烦 鉴于快速代码示例 import Control.Monad newtype LJ a = LJ {session :: a} 实例Monad LJ其中返回s = LJ s (>> =)mf = f(session m) 实例Functor LJ其中 fmap fm = LJ。 f $ session m type SimpleLJ = LJ String auth :: String - >字符串 - > SimpleLJ auth = undefined readFeed :: String - > SimpleLJ readFeed = undefined closeFeed :: String - > SimpleLJ closeFeed = undefined proceed = auth123456>> = readFeed>>> = closeFeed pre> 我该如何在Scala(而不是scalaz)中编写相同的相同的东西?据我了解,在scala中实现map / flatMap方法就足够了,但这里返回的是什么?如何在 for 语句中使用没有自由变量的绑定?解决方案我相信应该回答你的问题。它并不完全是直接的,因为它不利用在Scala中以模式形式存在的类型类型,因为在目前的情况下,它只会在没有真正原因的情况下过于复杂。 case class LJ [A](session:A){ //将其视为Haskell的fmap def map [B](f:A => B):LJ [B] = LJ(f(session)) //将其视为Haskell的>> = def flatMap [B](f :A => LJ [B]):LJ [B] = f(会话)} 类型SimpleLJ = LJ [字符串] def auth(a:String,b:String):SimpleLJ = ??? def readFeed(a:String):SimpleLJ = ??? close close(a:String):SimpleLJ = ??? def proceed:SimpleLJ = auth(123,456)。flatMap(readFeed).flatMap(closeFeed) //同上但是使用for-comprehension,它是 //用来替代Haskell的do--block def proceed2:SimpleLJ = for {a b c } 收益c 该解决方案演示了一种经典的面向对象的方法。使用这种方法,你不能在 LJ 类型中封装 return 函数,因为你最终在另一个级别上工作 - 不是与类型类型相同,而是类型实例。因此, LJ case类构造函数成为 return 的对应元素。 Trying to learn how to program monads in Scala, got some troublesGiven the quick code sampleimport Control.Monadnewtype LJ a = LJ { session :: a }instance Monad LJ where return s = LJ s (>>=) m f = f ( session m )instance Functor LJ where fmap f m = LJ . f $ session mtype SimpleLJ = LJ Stringauth :: String -> String -> SimpleLJauth = undefinedreadFeed :: String -> SimpleLJreadFeed = undefinedcloseFeed :: String -> SimpleLJcloseFeed = undefinedproceed = auth "123" "456" >>= readFeed >>= closeFeedhow do I write the same thing in Scala (not scalaz)? As far as I learned, it's enough to implement map/flatMap methods in scala, but what is return here? And how to do binding without free variables in for statement? 解决方案 Here's an almost direct translation, which I believe should answer your question. It's not completely direct because it doesn't utilize typeclasses which are present in form of a pattern in Scala, because in the current case it would have only overcomplicated things without a real reason.case class LJ[A]( session : A ) { // See it as Haskell's "fmap" def map[B]( f : A => B ) : LJ[B] = LJ( f( session ) ) // See it as Haskell's ">>=" def flatMap[B]( f : A => LJ[B] ) : LJ[B] = f( session )}type SimpleLJ = LJ[String]def auth( a : String, b : String ) : SimpleLJ = ???def readFeed( a : String ) : SimpleLJ = ???def closeFeed( a : String ) : SimpleLJ = ???def proceed : SimpleLJ = auth("123", "456").flatMap(readFeed).flatMap(closeFeed)// Same as above but using a for-comprehension, which is// used as a replacement for Haskell's "do"-blockdef proceed2 : SimpleLJ = for { a <- auth("123", "456") b <- readFeed(a) c <- closeFeed(b) } yield cThis solution demonstrates a classical object-oriented approach. With this approach you can't have the return function encapsulated in the LJ type because you end up working on another level - not on a type as with typeclasses, but on the instance of a type. So the LJ case class constructor becomes the counterpart of return. 这篇关于将Haskell monad直接翻译成Scala的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
05-27 06:04