繁体   English   中英

在Haskell中使用类型别名的正确方法是什么

[英]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

这将允许您继续使用真正独特的数据类型,而不是诉诸类型别名,它不会引入任何新类型,并且允许完全可互换地使用PuzzleMatrix Char而不增加类型安全性(也不具有表现力)。

此外,Jeffrey的正确之处在于newtype更类似于data不是type - newtype提供了对data一些性能优化,但是更受限制并且稍微影响了程序评估语义。 您最好阅读有关在Haskell中定义类型和类型别名的各种方法。

在您的情况下,您也可以在不改变程序行为的情况下替换newtype data ; 程序的其余部分应继续以相同的方式工作。

另请参阅: Haskell类型与newtype相关的类型安全性

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM