Haskell 一个函数的类型签名是什么?它既可以应用于(&;f%~)也可以应用于(^.f),其中操作符来自透镜库?
我有一个函数,它从一条记录中获取一个值,并将其设置为另一条记录中的同一字段 我想做的是了解它背后的机制是如何工作的Haskell 一个函数的类型签名是什么?它既可以应用于(&;f%~)也可以应用于(^.f),其中操作符来自透镜库?,haskell,haskell-lens,type-signature,Haskell,Haskell Lens,Type Signature,我有一个函数,它从一条记录中获取一个值,并将其设置为另一条记录中的同一字段 我想做的是了解它背后的机制是如何工作的 setToPercent perc basedOn toSetOn = setStat where baseStat = basedOn ^. _func -- type is Maybe Float percentDelta = (\a -> perc * a) <$> baseStat -- Maybe Float
setToPercent perc basedOn toSetOn = setStat
where baseStat = basedOn ^. _func -- type is Maybe Float
percentDelta = (\a -> perc * a) <$> baseStat -- Maybe Float
setStat = toSetOn & _func %~ (\a -> (+) <$> a <*> percentDelta)
有趣的问题
我知道这里basedOn^_func
,\u func
将具有类型get(f0 Float)MyDataType(f0 Float)
在这里,Toston&_func%~(\a->(+)a percentDelta
,_func
将具有类型a更好的武器(f0浮动)(f0浮动)
因此,非正式地说,\u func
既是一个getter又是一个setter。看看上面的图表或Oleg Grenrus的图表,getter和setter的“最不常见祖先”是lents
镜头库提出了至少两种镜头表示法,一种是多态的lens'武器(f0 Float)
(定义包含forall
),另一种是单态的ALens'武器(f0 Float)
(用具体的函子替换forall
)
由于我们希望这里的\u func
自动专门化为ASetter
和get
,一种简单的方法是使用多态方法(如果\u func
是一个参数而不是顶级绑定,则需要RankNTypes
)
还有另一种使用单态版本的方法。当\u func
是函数参数时,我发现这更为惯用,因为它使调用方更容易传入合适的参数。然而,我们必须在实际使用它时显式地概括\u func
_func :: ALens' Weapon (f0 Float) -- Monomorphic
cloneLens _func :: Lens' Weapon (f0 Float) -- Polymorphic again
-- The ALens' type synonym usually appears in argument position
myFun :: ALens' Foo Bar -> MyResult
myFun _func = ...
-- Example usage
basedOn ^. cloneLens _func
toSetOn & cloneLens _func %~ ...
感谢您的回答!两个版本都很好地工作!我还必须将
(Functor f0,Applicative f0)
添加到类型的上下文中,以允许使用
,
&
。
_func :: Lens' Weapon (f0 Float) -- Polymorphic
-- specializes to
:: Getting (f0 Float) Weapon (f0 Float)
:: ASetter' Weapon (f0 Float)
_func :: ALens' Weapon (f0 Float) -- Monomorphic
cloneLens _func :: Lens' Weapon (f0 Float) -- Polymorphic again
-- The ALens' type synonym usually appears in argument position
myFun :: ALens' Foo Bar -> MyResult
myFun _func = ...
-- Example usage
basedOn ^. cloneLens _func
toSetOn & cloneLens _func %~ ...