Types &引用;嵌套的;elm中的并集类型
我正在学习elm,并试图从TypeScript的类型系统转换我的思维方式。我想知道使用嵌套类型的最佳方式是什么:Types &引用;嵌套的;elm中的并集类型,types,elm,union-types,Types,Elm,Union Types,我正在学习elm,并试图从TypeScript的类型系统转换我的思维方式。我想知道使用嵌套类型的最佳方式是什么: type Player = X | O type Cell = Player | Empty viewCell: Cell -> string viewCell cell = case cell of X -> "X" O -> "O" Empty -> " " check: (List Cell) -> string
type Player = X | O
type Cell = Player | Empty
viewCell: Cell -> string
viewCell cell =
case cell of
X -> "X"
O -> "O"
Empty -> " "
check: (List Cell) -> string
check three =
case three of
[X, X, X] -> "X won"
[O, O, O] -> "O won"
_ -> "still going"
type Player = X | O
type Cell = Player Player | Empty
viewCell: Cell -> String
viewCell cell =
case cell of
Player X -> "X"
Player O -> "O"
Empty -> " "
编译器抱怨
The first pattern is trying to match `X` values of type:
Player
But the expression between `case` and `of` is:
Cell
我可以像这样更改viewCell,但我不知道如何获得播放器
viewCell: Cell -> String
viewCell cell =
case cell of
Player -> -- how to get the player ??
Empty -> " "
问题不是显示值本身,而是“解构”嵌套的联合类型。我想稍后在类似这样的内容中使用它:
type Player = X | O
type Cell = Player | Empty
viewCell: Cell -> string
viewCell cell =
case cell of
X -> "X"
O -> "O"
Empty -> " "
check: (List Cell) -> string
check three =
case three of
[X, X, X] -> "X won"
[O, O, O] -> "O won"
_ -> "still going"
type Player = X | O
type Cell = Player Player | Empty
viewCell: Cell -> String
viewCell cell =
case cell of
Player X -> "X"
Player O -> "O"
Empty -> " "
这也给了我编译器类似的抱怨构造函数和类型唯一可以共享名称的时候是如果您执行以下操作:
type Tag=Tag String
考虑一下你说过的话
type Cell=Player|Empty
但也可能需要
type Winner=Player |无
那么什么是Player
?它是单元格
还是赢家
?不可能两者都有
简单的解决办法是:
type Cell=PlayerCell Player|Empty
type Winner=WinningPlayer | None
PlayerCell X
是一个包含玩家X的单元格。winning玩家O
是赢家
分解结构时,可以嵌套:
case cell of
PlayerCell X ->
...
PlayerCell O ->
...
Empty ->
...
事实上,您可以分解更复杂的数据结构:
case cellRow of
[ PlayerCell O, PlayerCell O, PlayerCell O] ->
...
在
Player
不是一个类型,而是一个类型为Cell
的值。但是,您也可以给它一个参数,在这种情况下,它将是一个值构造函数,当给它一个参数时,它将返回一个类型为Cell
的值。所以在
type Player = X | O
type Cell = Player Player | Empty
Player-Player
中的第一个Player
基本上是一个函数,当给定类型为Player
的值时,该函数将返回类型为Cell
的值。或者键入speak中的Player->Cell
还要注意,类型和构造函数可以具有相同的名称,因为它们位于不同的域中。它们并不冲突,因为它们引用不同的东西,一个引用类型,另一个引用值(构造函数)。但事实上,你可以,并不一定意味着你应该,因为它可以相当混乱
然后,您可以在单元格
和嵌套的播放器
上进行模式匹配,如下所示:
type Player = X | O
type Cell = Player | Empty
viewCell: Cell -> string
viewCell cell =
case cell of
X -> "X"
O -> "O"
Empty -> " "
check: (List Cell) -> string
check three =
case three of
[X, X, X] -> "X won"
[O, O, O] -> "O won"
_ -> "still going"
type Player = X | O
type Cell = Player Player | Empty
viewCell: Cell -> String
viewCell cell =
case cell of
Player X -> "X"
Player O -> "O"
Empty -> " "
Player
和Empty
这里指的是单元格的构造函数/变体,而不是类型。同样地,X
和O
指的是Player
的变体,它们也不是类型。谢谢!所以我想没有办法像我的第一个例子那样“解构”类型?您是否有任何书籍或文章推荐,以更好地理解elm的类型系统?我认为初学者elm Slack是学习基础知识时快速获得答案的好地方。在我的答案中添加了更复杂的分解。