【问题标题】:Parametrised data type in ScalaScala中的参数化数据类型
【发布时间】:2011-10-05 08:59:40
【问题描述】:

在阅读文章 "Data types a la carte" by Wouter Swierstra 时,我一直无法将以下 Haskell 代码翻译成 Scala:

data Expr f = In (f (Expr f ))

Expr是用于表示算术表达式的数据类型,具体表达式可以写成如下:

data Val e = Val Int
type IntExpr = Expr Val

data Add e = Add e e
type AddExpr = Expr Add

我的问题是在 Scala 中实现f(可能被认为是构造函数的签名)。

P.S. 定义两个签名的联积,您可以稍后组合数据类型,得到 Expr (Val :+: Add ) 类型的表达式:

data (f :+: g) e = Inl (f e) | Inr (g e)

addExample :: Expr (Val :+: Add )
addExample = In (Inr (Add (In (Inl (Val 118))) (In (Inl (Val 1219)))))

【问题讨论】:

  • nb -- adt 是关于“Android 开发工具”,而不是关于代数数据类型,无论如何,应用于数据类型的首字母缩写词 ADT 通常意味着 抽象,而不是代数
  • 有两个问题阻碍了以简单的方式实现这一点:1)通用量化。 2) 高阶统一。

标签: scala haskell types


【解决方案1】:

可能是这样的

case class Expr[f[_]] (in : f [Expr[f]])

虽然这不如在 Haskell 中有用。假设你定义

case class Val[e] (v: Int)

那么Val(3) 将具有Val[Nothing] 的类型,您不能将它与Expr 一起使用。

scala> val e = Expr(Val(3))               
<console>:9: error: no type parameters for method apply: 
(in: f[Expr[f]])Expr[f] in object Expr exist so that it can be applied 
to arguments (Val[Nothing])
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Val[Nothing]
 required: ?f[ Expr[?f] ]
       val e = Expr(Val(3))

您仍然可以明确指定类型

val e = Expr(Val(3):Val[Expr[Val]])

但这并不好玩。你当然可以定义一个正确类型的函数并使用它来代替 Val。

请注意,我仍然是 Scala 菜鸟,也许还有更优雅的方法。

【讨论】:

    【解决方案2】:

    我突然发现这个blogpost 提供了一些关于将“点菜数据类型”翻译成 Scala 的很好的解释。建议的解决方案如下:

    case class Val[E](i: Int)
    case class Add[E](left: E, right: E)
    
    case class Expr[F[X]](e: F[Expr[F]])
    
    sealed trait Sum[F[X], G[X], E]
    case class Inl[F[X], G[X], E](l: F[E]) extends Sum[F,G,E]
    case class Inr[F[X], G[X], E](r: G[E]) extends Sum[F,G,E]
    
    trait Apply2Of3[F[A[_],B[_],_],A[_],B[_]] {
            type It[C] = F[A,B,C]
    }
    
    type Tmp[X] = Apply2Of3[Sum,Val,Add]#It[X]
    
    val addExample: Expr[Tmp] = In[Tmp](Inr(Add(In[Tmp](Inl(Val(118))), In[Tmp](Inl(Val(1219))))))
    

    它远没有最初的(用 Haskell 制作)那么甜美,但在以下方面非常有用:1)它证明了在 Scala 中实现这个想法通常是可能的,2)提出了 Scala 的一些弱点与 Haskell 相比。

    【讨论】:

      猜你喜欢
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 2021-04-20
      相关资源
      最近更新 更多