简体   繁体   English

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

[英]What's the right way to use type aliases in Haskell

I'm a total beginner with Haskell. 我是Haskell的初学者。 While trying to solve some practise exercises on hackerrank I stumbled over an error which makes me wonder to do it "the right way"(tm). 在尝试解决关于hackerrank的一些练习练习时,我偶然发现了一个错误,这让我想知道“正确的方式”(tm)。

What I was trying to do was this: 我试图做的是这样的:

import Data.Matrix

newtype Puzzle = Matrix Char

complete :: Puzzle -> Bool
complete p = '-' `elem` (toList p)

[... more functions using 'Matrix Char']

what gave me 什么给了我

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)’

The obvious solution is of course just using Matrix Char instead of Puzzle . 显而易见的解决方案当然只是使用Matrix Char而不是Puzzle But I don't feel that this is an elegant solution. 但我觉得这不是一个优雅的解决方案。 An abstraction into a more specific type feels the right way to go... 抽象为更具体的类型感觉是正确的方式...

Use type not newtype . 使用type而不是newtype The former creates a type alias, the latter is a new type declaration. 前者创建一个类型别名,后者是一个新类型声明。 Specifically newtype is kind of special case for data , where the new type represents a "wrapper" over an existing type (which is a case that can be optimized by the compiler). 具体地说newtype是种特殊情况下data ,其中,所述新类型表示一个“包装”在现有的类型(这是可以由编译器进行优化的情况下)。

I think a better solution than the one offered by Jeffrey's answer, at least in the case of more substantial code bases than a toy game, is to keep using newtype but to change the code to this: 我认为比Jeffrey的答案提供的更好的解决方案,至少在比玩具游戏更具实质性的代码基础的情况下,是继续使用newtype但是将代码更改为:

import Data.Matrix

newtype Puzzle = Puzzle (Matrix Char)

complete :: Puzzle -> Bool
complete (Puzzle matrix) = '-' `elem` toList matrix

This will allow you to keep using a truly distinct data type as opposed to resorting to a type alias, which doesn't introduce any new types and will allow completely interchangeable use of Puzzle and Matrix Char with no added type safety (nor expressiveness). 这将允许您继续使用真正独特的数据类型,而不是诉诸类型别名,它不会引入任何新类型,并且允许完全可互换地使用PuzzleMatrix Char而不增加类型安全性(也不具有表现力)。

Also, Jeffrey is right in that newtype is more similar to data than typenewtype offers some performance optimisations over data but is more restricted and slightly affects the program evaluation semantics. 此外,Jeffrey的正确之处在于newtype更类似于data不是type - newtype提供了对data一些性能优化,但是更受限制并且稍微影响了程序评估语义。 You're better off reading up on all the various ways of defining types and type aliases in Haskell. 您最好阅读有关在Haskell中定义类型和类型别名的各种方法。

In your case, you might as well substitute data for newtype without changing the behavior of your program; 在您的情况下,您也可以在不改变程序行为的情况下替换newtype data ; the rest of the program should continue to work identically. 程序的其余部分应继续以相同的方式工作。

See also: Haskell type vs. newtype with respect to type safety 另请参阅: Haskell类型与newtype相关的类型安全性

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

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