Haskell 理解作者类型
我在《给你学哈斯卡尔好东西》一书中了解了单子米兰·利波瓦卡。我正在阅读Control.Monad.Writer模块如何导出Haskell 理解作者类型,haskell,syntax,functional-programming,monads,record,Haskell,Syntax,Functional Programming,Monads,Record,我在《给你学哈斯卡尔好东西》一书中了解了单子米兰·利波瓦卡。我正在阅读Control.Monad.Writer模块如何导出Writer w a类型及其Monad实例和一些用于处理此类型值的有用函数 对于以下代码: newtype Writer w a = Writer { runWriter :: (a,w) } 我知道atype参数表示某个值的类型,wtype参数表示附加的幺半群值的类型。通过将w和a传递给Writer类型构造函数,您可以得到一个Writer单子作为回报,而这个单子只有一个函
Writer w a
类型及其Monad实例和一些用于处理此类型值的有用函数
对于以下代码:
newtype Writer w a = Writer { runWriter :: (a,w) }
我知道a
type参数表示某个值的类型,w
type参数表示附加的幺半群值的类型。通过将w
和a
传递给Writer
类型构造函数,您可以得到一个Writer单子作为回报,而这个单子只有一个函数,即runWriter
函数,这是对的吗
在这本书中,它说runWriter
函数获取一个包装在Writer
newtype中的元组并将其展开,返回一个简单的元组。但是runWriter
的类型声明是runWriter::(a,w)
,它不接受任何参数作为输入。runWriter
如何获取用newtype包装的元组并只返回一个简单的元组
通过将w
和a
传递给Writer类型构造函数,您可以得到Writer monad作为回报,这是正确的吗
否,Writer w
是monad(假设Monoid w
)<代码>编写器w a是一种类型
这个单子只有一个函数,那就是runWriter
函数
不,类型Writer wa
本质上是成对类型(a,w)
。里面没有函数
您可以假设该类型是按以下方式定义的
newtype Writer w a = Writer (a,w)
还有一个单独的方便的“展开”功能
您可以将这些函数视为相互反转:
Writer :: (a,w) -> Writer w a -- "wrapper"
runWriter :: Writer w a -> (a,w) -- "unwrapper"
使用data
声明中的记录语法确实定义了采用隐式参数的函数(除了数据类型本身)。
任何类型
定义数据类型T
、数据构造函数MkT
、函数f
、具有隐式T
参数的g
f :: T -> Int -- f (MkT i _) = i
g :: T -> String -- g (MkT _ s) = s
使用
newtype
s录制语法的工作方式相同,只是必须只有一个字段(在您的示例中名为runWriter
)对于您的示例,runWriter(Writer p)=p,我说Writer p是monad是正确的吗?那么本质上runWriter(Writer p)=p将取出monad中的任何内容?还有,你怎么知道Writer wa是成对类型的呢?任何见解都值得赞赏。@ceno980Writer p
是一个值,因此它不能是monad,这是类型级别的东西。我们可以说,Writer p
是一个“一元值”,即对于某些单子m
和a
类型,是ma
类型的值。runWriter
提取Writer
包装下的内容是正确的Writer wa
本质上是一对,因为它是这样定义的:如果我们把newtype T=T{runT::a}
放在一起,那么类型T
和a
本质上是相同的——它们只是名称不同而已。您可以将x::A
转换为tx::T
,然后将y::T
转换为runT y::A
,而不会丢失信息。如果您以newtype Writer w A=MkWriter(A,w)
的形式编写,则不会将数据(MkWriter p
)与类型(Writer w A
)混淆@ceno980@chi对于此行:data T=MkT{f::Int,g::String}。基本上,数据类型T有一个值构造函数MkT,它有两个字段f和g,分别是Int和String类型。为了创建一个值为Int/String的字段,必须将数据类型本身(T)传递给函数f/g以获取值?这对吗?@ceno980不太对。我们可以构造T
值,如x=mkt1“a”
;我们可以用fx==1
和gx==“b”
处理这些值。但是,我们也可以使用记录语法来创建值,比如x=MkT{g=“a”,f=1}
。然后是记录更新语法y=x{f=2}
。
data T = MkT { f :: Int, g :: String }
f :: T -> Int -- f (MkT i _) = i
g :: T -> String -- g (MkT _ s) = s