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

Haskell 为什么通常使用newtype而不是状态为monad的类型,haskell,state-monad,newtype,Haskell,State Monad,Newtype,我所看到的状态Monad的几乎所有示例都被包装在newtype中 {-# LANGUAGE GeneralizedNewtypeDeriving #-} import Control.Monad.State import Control.Applicative data Bazzar = Bazzar { valueOne :: Int , valueTwo :: Int } newtype BazState a = BazState { un

我所看到的
状态
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
的目的是区分同一类型数据结构的两种不同用途,比如为现有类型重新实现类型类,或者如果您想将类型的使用与正常行为区分开来。或者实现额外的TypeClass以使用该类


如果您没有执行上面提到的任何操作,那么在本例中使用
newtype
是否只是不必要的间接操作?

除了能够定义新类型的实例之外,您还可以将其用作库的“封闭构造函数”API。这样,您可以在不使用任何构造函数的情况下导出单个类型,以及充当原语和组合符的函数,这样库的用户就不能构造类型的无效值。这还意味着,如果足够小心,可以在不破坏外向API的情况下更改底层结构。尼尔·米切尔就是一个很好的例子:

Haskell很酷的一点是,我能够完全替换底层的Shake
操作
monad,从
StateT/IO
,到
ReaderT/IO
,再到
ReaderT/ContT/IO
,而不破坏任何Shake用户。Haskell允许我生成有效且灵活的抽象


无法定义类型同义词的实例。是否确定?我可以毫无问题地在ghci中输入
类型Blah a=[(Int,a)]
。哦,等等,我只是重读了你说的,这很公平。问题是我看到的大多数示例都没有实现任何额外的类型类。我将更新我的问题它还允许您以这样一种方式导出api,即您可以为库导出monad或其他类型,而无需导出其构造函数,并且如果您将来需要更改基础类型,则在不破坏外向api的情况下更容易执行此操作。这是一个很好的观点,我实际上并没有把它当作一个用例,请随意回答这个问题。