将Scala类型示例转换为Haskell
发布时间:2020-12-16 19:02:18 所属栏目:安全 来源:网络整理
导读:我在 Scala文章中发现了一个非常有趣的例子,我想知道如何在Haskell中进行编码. trait Statustrait Open extends Statustrait Closed extends Statustrait Door[S : Status]object Door { def apply[S : Status] = new Door[S] {} def open[S : Closed](d: Do
我在
Scala文章中发现了一个非常有趣的例子,我想知道如何在Haskell中进行编码.
trait Status trait Open extends Status trait Closed extends Status trait Door[S <: Status] object Door { def apply[S <: Status] = new Door[S] {} def open[S <: Closed](d: Door[S]) = Door[Open] def close[S <: Open](d: Door[S]) = Door[Closed] } val closedDoor = Door[Closed] val openDoor = Door.open(closedDoor) val closedAgainDoor = Door.close(openDoor) //val closedClosedDoor = Door.close(closedDoor) // fails to compile //val openOpenDoor = Door.open(openDoor) // fails to compile 该样本在类型级别进行编码,您只能打开一个关闭的门,并且只关闭一个打开的门.我的第一次尝试只是使用简单的数据类型,但不能按照预期的方式工作: data Status = Open | Closed deriving (Show) data Door = Door Status deriving (Show) open :: Door -> Door open (Door Closed) = Door Open close :: Door -> Door close (Door Open) = Door Closed main = do let closedDoor = (Door Closed) let openDoor = open closedDoor let closedAgainDoor = close openDoor let closeClosedDoor = close closedDoor let openOpenedDoor = open openDoor print closedAgainDoor 这实际上是编译(除非我尝试打印closeClosedDoor或openOpenedDoor,然后在功能打开中抱怨非穷尽的模式,这是显而易见的) 所以我试图弄清楚,我们的类型家庭的GADT是否可以完成这个任务,但是我还不能掌握如何. 有任何想法吗? 解决方法
除了bheklilr的答案之外,您可以使用一些类型扩展来更接近Scala示例,并排除非感性类型,例如
Door String 使用DataKinds,您可以有效地禁止幻像类型作为状态. {-# LANGUAGE DataKinds #-} data Door (status :: Status) = Door data Status = Open | Closed open :: Door Closed -> Door Open open _ = Door close :: Door Open -> Door Closed close _ = Door 那么,对于类型的家庭,我们甚至可以定义“切换”门的意义 {-# LANGUAGE TypeFamilies #-} type family Toggle (s :: Status) where Toggle Open = Closed Toggle Closed = Open toggle :: Door s -> Door (Toggle s) toggle Door = Door 作为一个闭幕式,使用GADT for Door可能更好 – 只是因为您有两个不同的构造函数名称.我个人认为这样看起来更好 {-# LANGUAGE GADTs,DataKinds,TypeFamilies #-} data Door (status :: Status) where OpenDoor :: Door Open ClosedDoor :: Door Closed open :: Door Closed -> Door Open open _ = OpenDoor close :: Door Open -> Door Closed close _ = ClosedDoor toggle :: Door s -> Door (Toggle s) toggle OpenDoor = ClosedDoor toggle ClosedDoor = OpenDoor (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容