给定一个执行以下操作的函数:(a-> a)我们应该将该函数并将其类型转换为(也许a->也许a)。我有点坐在这里,尝试所有可能的方法,但是我得到的只是Maybe类型(a-> a),但我不知道要更改实际的输入和输出。因此,有人可以给我一些有关解决此问题的提示或想法,以便我自己尝试吗?谢谢。
假设你有
f :: a -> a
而你需要构造
g :: Maybe a -> Maybe a
g = ...
我们如何构造它?首先,它是一个参数的函数,因此应类似于:
g = \x -> ...
其次,我们有一个type类型的参数Maybe
,因此我们可以分别分析两种情况:
g = \x -> case x of
Nothing -> ... (1)
Just y -> ... (2)
在(1)中,我们不能做很多事情:我们不能产生抽象类型的值a
,所以不能使用Just
。我们唯一可以使用的是Nothing
。
在(2)中,我们有三个选项:
a)Nothing
再次,所以我们得到一个无聊的解决方案:
g = \x -> case x of
Nothing -> Nothing
Just y -> Nothing
这很简单
g = \x -> Nothing
b)或者,我们有一个y::a
,因此我们可以返回Just y
:
g = \x -> case x of
Nothing -> Nothing
Just y -> Just y
这很简单
g = \x -> x -- = id
C)或者,我们可以申请f
到y
,要获得类型的新价值a
。然后,我们要做的就是将此值包装在中Just
:
g = \x -> case x of
Nothing -> Nothing
Just y -> Just (f y)
正如@chi所指出的,我们可以继续应用f
结果,因此我们也可以返回Just (f (f ... (f y)...))
任意数量的f
s。
只有(c)曾经使用过f
,因此这是这里唯一不平凡的解决方案。
为了完整起见,值得注意的是,对于实际应用而言,(b)和(c)都是等效的,f
除了之外什么都不能id
。
作为@amalloy指出,这是不是这样,如果我们采取f
作为一个参数,而不是全局函数,仅id
可以作为a->a
任何a
,但也有许多类型的功能a->a
给定a
。所以如果你g
应该
g :: (a->a)->(Maybe a->Maybe a)
那么(b)和(c)不再是同一件事。
可以肯定的是,可以用多种方式来编写:上面的朴素版本,使用事实Maybe
是a Monad
,使用fmap
from Functor Maybe
(贷方为@amalloy),但结果将是相同的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句