为什么通常使用newtype而不是使用状态monad的类型

时间:2014-08-23 14:22:51

标签: haskell state-monad newtype

我见过State Monad的几乎所有例子都被包裹在newtype内。

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.State
import Control.Applicative

data Bazzar 
  = Bazzar {
    valueOne :: Int      
  , valueTwo :: Int      
  }

newtype BazState a = BazState { unBazify :: State Bazzar a } 
  deriving (Functor, Applicative, Monad, MonadState Bazzar)

有什么理由我不应该只是做一个类型别名吗?

type BazState a = State Bazzar a

我意识到newtype的目的是区分同一类型数据结构的两种不同用途,例如为现有类型重新实现类型类,或者如果要区分对类型的使用与正常行为的区别。或者实现其他类型类以使用该类

如果你没有做上面提到的任何事情,在这种情况下是不是使用newtype只是不必要的间接?

1 个答案:

答案 0 :(得分:3)

除了能够为newtype定义实例之外,您还可以将其用作"关闭的构造函数"您的图书馆的API。这样,您可以导出一个没有任何构造函数的单一类型,以及充当基元和组合器的函数,这样您的库的用户就无法构造您的类型的无效值。这也意味着,如果您足够小心,可以在不破坏外向API的情况下更改底层结构。一个很好的例子来自Neil Mitchell,who said in a recent post about modifying the Shake build system to use the Continuation monad

  

关于Haskell的一个很酷的事情是,我已经能够从ActionStateT/IOReaderT/IO完全取代底层的Shake ReaderT/ContT/IO monad,没有破坏Shake的任何用户。 Haskell允许我产生有效和灵活的抽象。