mBr*_*024 4 haskell functor newtype
假设我要定义一个包含函数的新类型:
newtype Test m a = Test(m -> (a, m))
Run Code Online (Sandbox Code Playgroud)
这可以用来容纳某种状态。
现在让我们说我想为这个新类型实现fmap。
instance Functor (Test m) where
--fmap :: (a -> b) -> Test m a -> Test m a -> b
fmap f (Test f1) (Test f2) = ?
Run Code Online (Sandbox Code Playgroud)
由于新类型房屋具有功能,因此无法使用模式匹配将f1和f2分开。
例如,我最初认为我可以将f2的输入值传递给调用f1以产生一个(a,m)元组,但是我认为您不能做到这一点。
即
tup = f1 (get input of f2)
Run Code Online (Sandbox Code Playgroud)
有人能为我提供处理这种情况时我所缺少的概念吗?或者这不可能吗?
谢谢
更新
非常感谢Redu和Willem Van Onsem。
似乎我对如何使用合成运算符(。)缺乏了解。
基本上,这里的关键是使用(。)来获取元组的第一个元素,然后执行一堆局部函数定义以进入fmap所需的状态。这是我的fmap实现,没有使用库函数。故意冗长以帮助理解。
alterParamStateHelper :: (a -> b) -> (m -> a) -> m -> (b, m)
alterParamStateHelper f1 f2 m = (b, m)
where
a = f2 e
b = f1 a
alterParamState :: (a -> b) -> (m -> (a, m)) -> (m -> (b, m))
alterParamState f1 f2 = alterParamStateHelper f1 h1
where
h1 = fst . f2--m -> a
instance Functor (Test m) where
-- fmap :: (a -> b) -> Test m a -> Test m b
fmap f1 (Test f2) = Test (alterParamState f1 f2)
Run Code Online (Sandbox Code Playgroud)
由于新类型具有功能,因此无法使用模式匹配进行拆分
f1和f2分离。
您的fmap签名在这里有问题。fmap有签名fmap :: Functor f => (a -> b) -> f a -> f b,如果是f ~ Test m,那么签名是fmap :: (a -> b) -> Test m a -> Test m b。
因此fmap,我们可以在此处定义一个“后处理”函数结果的位置。因此,我们构造了一个新函数,该函数将使用旧函数构造一个2元组(a, m),然后调用f第一个项目,从而构造一个元组(b, m):
import Control.Arrow(first)
instance Functor (Test m) where
fmap f (Test g) = Test (first f . g)Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |