2016-06-10 31 views
7

Haskell Ücretsiz uygulamasıdır:Ücretsiz uygulama

:

sealed abstract class Free[S[_], A] 

private case class Return[S[_], A](a: A) extends Free[S, A] 
private case class Suspend[S[_], A](a: S[A]) extends Free[S, A] 
private case class Gosub[S[_], B, C](a: Free[S, C], f: C => Free[S, B]) extends Free[S, B] 

neden olduğu gibi, Haskell benzer scalaz uygulama değildir: Scalaz içinde uygulanması, oysa

data Free f a = 
Pure a 
| Free (f (Free f a)) 

sealed trait Free[F[_],A] 
case class Return[F[_],A](a: A) extends Free[F,A] 
case class GoSub[F[_],A](s: F[Free[F,A]]) extends Free[F,A] 

Bu iki uygulama da izomorfik midir?

+0

İkinci Scala uygulamasını kullanarak bir 'F [A]' verildiğinde nasıl bir 'Free [F, A]' yaratabilirsiniz? –

+0

@PeterNeyens 'F' bir' Functor' olduğunda çok iyi bir şekilde mümkündür. Bu temsil ile ilgili problem, yığın güvenliği sorunlarına yol açmasıdır. –

+1

@TomasMikula. Tamam, GoSub'u görüyorum [F, A] (F.map (fa) (İade [F, A] (_))), teşekkürler! –

cevap

7

Scala o Haskell kod çeviri

sealed abstract class Free[S[_], A] 

case class Return[S[_], A](a: A) extends Free[S, A] 
case class Suspend[S[_], A](a: S[Free[S, A]]) extends Free[S, A] 

Haskell uygulama tembel değerlendirmeye Gosub vaka sayesinde ihtiyaç duymaz olur. Bu temsil, Scala'da da işe yarayacaktı, ancak (katı değerlendirme ve) kuyruk-çağrı eleme eksikliğinden dolayı yığılma-taşma sorunlarına yol açacaktır. Gosub (Ben FlatMap iyi bir isim olacağını düşünüyorum) gibi yığını güvenli hale getirmek için, biz tembel flatMap temsil: Bir bonus olarak

case class Gosub[S[_], B, C](a: Free[S, C], f: C => Free[S, B]) extends Free[S, B] 

, Gosub giriş bize

case class Suspend[S[_], A](a: S[A]) extends Free[S, A] 
için Suspend basitleştirmek için izin verir

biz artık S[_] içeriği üzerinde haritalama tarafından — flatMap s yapmak gerekmez çünkü biz flatMap s açıkça Gosub olarak s temsil eder. Sonuç olarak, bu ortaya çıkan temsil, Haskell temsilinden farklı olarak,'a ihtiyaç duymadan, Free ile ilgili herşeyi yapmamızı sağlar. Dolayısıyla, S bizim Functor değilken "Coyoneda trick" ile uğraşmak zorunda bile değiliz.

İlgili konular