美文网首页Haskell
[Haskell] newtype

[Haskell] newtype

作者: 何幻 | 来源:发表于2016-03-04 07:14 被阅读265次

    ——以下译自《Real World Haskell》P157

    <u></u>newtype关键字,用来给已存在的类型,设置一个新的身份。
    <u></u>newtypedata限制更多,newtype只能有一个值构造器,且这个值构造器只能有一个字段

    反例:

    -- no fields
    newtype TooFew = TooFew
    
    -- more than one field
    newtype TooManyFields = Fields Int Int
    
    -- more than one constructor
    newtype TooManyCtors = Bad Int | Worse Int
    

    除此之外,datanewtype还有另外一个区别。
    使用data创建的类型,在运行时具有簿记的花销,因为要跟踪该类型的值是由哪个值构造器创建的。
    newtype创建的类型,因为只能有一个值构造器,所以没有这种负担,这使得在运行的时候,无论在时间还是空间上都更有效率。

    因为newtype的值构造器,只用于编译时,在运行时是不存在的
    所以,对于undefined进行模式匹配时,newtype定义类型的值和data定义类型的值,表现方式是不同的。

    我们使用data来定义一个DataInt类型,使用newtype来定义一个NewtypeInt类型

    data DataInt = D Int
    deriving (Eq, Ord, Show)
    
    newtype NewtypeInt = N int
    deriving (Eq, Ord, Show)
    

    我们知道,undefined如果在运行时被求值,就会导致程序崩溃。

    ghci> undefined
    *** Exception: Prelude.undefined
    

    [类型DataInt,情况1]
    由于Haskell的模式匹配是惰性的,所以如果undefined不需要被求值时,程序不会崩溃。

    ghci> case D undefined of D _ -> 1
    1
    

    [类型DataInt,情况2]
    但是,当undefined必须求值才能完成模式匹配时,程序就会崩溃。

    ghci> case undefined of D _ -> 1
    *** Exception: Prelude.undefined
    

    我们将以上DataInt类型的值构造器,换成NewtypeInt类型的值构造器N,结果如下:

    [类型NewtypeInt,情况1],与[类型DataInt,情况1],相同

    ghci> case N undefined of N _ -> 1
    1
    

    [类型NewtypeInt,情况2],与[类型DataInt,情况2],不同

    ghci> case undefined of N _ -> 1
    1
    

    这里程序并不会崩溃,因为在运行时,已经没有NewtypeInt类型的值构造器N了。
    对“N _”进行匹配,事实上就是对“_”进行匹配。
    而“_”总是会满足匹配条件,所以undefined是不需要被求值的。

    相关文章

      网友评论

        本文标题:[Haskell] newtype

        本文链接:https://www.haomeiwen.com/subject/dlunkttx.html