[英]What's the right way to use type aliases in Haskell
我是Haskell的初学者。 在尝试解决关于hackerrank的一些练习练习时,我偶然发现了一个错误,这让我想知道“正确的方式”(tm)。
我试图做的是这样的:
import Data.Matrix
newtype Puzzle = Matrix Char
complete :: Puzzle -> Bool
complete p = '-' `elem` (toList p)
[... more functions using 'Matrix Char']
什么给了我
Couldn't match expected type ‘Matrix Char’
with actual type ‘Puzzle’
In the first argument of ‘toList’, namely ‘p’
In the second argument of ‘elem’, namely ‘(toList p)’
显而易见的解决方案当然只是使用Matrix Char
而不是Puzzle
。 但我觉得这不是一个优雅的解决方案。 抽象为更具体的类型感觉是正确的方式...
使用type
而不是newtype
。 前者创建一个类型别名,后者是一个新类型声明。 具体地说newtype
是种特殊情况下data
,其中,所述新类型表示一个“包装”在现有的类型(这是可以由编译器进行优化的情况下)。
我认为比Jeffrey的答案提供的更好的解决方案,至少在比玩具游戏更具实质性的代码基础的情况下,是继续使用newtype
但是将代码更改为:
import Data.Matrix
newtype Puzzle = Puzzle (Matrix Char)
complete :: Puzzle -> Bool
complete (Puzzle matrix) = '-' `elem` toList matrix
这将允许您继续使用真正独特的数据类型,而不是诉诸类型别名,它不会引入任何新类型,并且允许完全可互换地使用Puzzle
和Matrix Char
而不增加类型安全性(也不具有表现力)。
此外,Jeffrey的正确之处在于newtype
更类似于data
不是type
- newtype
提供了对data
一些性能优化,但是更受限制并且稍微影响了程序评估语义。 您最好阅读有关在Haskell中定义类型和类型别名的各种方法。
在您的情况下,您也可以在不改变程序行为的情况下替换newtype
data
; 程序的其余部分应继续以相同的方式工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.