是否可以实现此功能?

Mat*_*ick 5 haskell function list

我想要一个q类型的功能:

q :: ([b] -> b) -> ([(a, b)] -> (a, b))
Run Code Online (Sandbox Code Playgroud)

它接受一个从列表中选择单个元素的函数,并将该函数提升到从一对列表中选择单个对的上下文中(完全忽略对的第一个元素).

甚至可以编写这样的功能吗?我未能在此方面取得任何进展.

*是'解除'正确的词?


使用示例:如果我有一个功能:

safeMaximum :: b -> [b] -> b

> safeMaximum 18 [] 
18
> safeMaximum 18 [4,5,1,4,3]
5
Run Code Online (Sandbox Code Playgroud)

然后我想用来safeMaximum从对列表中得到第二个元素最大的对:

liftedSafeMaximum :: (a, b) -> [(a, b)] -> (a, b)
liftedSafeMaximum val = q val safeMaximum

liftedSafeMaximum ("?", 3) []
> ("?", 3)
liftedSafeMaximum ("?", 3) [("xyz", 1), ("123", 3), ("hi", 2)]
> ("123", 3)
Run Code Online (Sandbox Code Playgroud)

C. *_*ann 3

您将其描述为想要“将函数提升到上下文中”,所以让我们看看这意味着什么。从所需的类型开始:

q :: (a, b) -> ([b] -> b) -> ([(a, b)] -> (a, b))
Run Code Online (Sandbox Code Playgroud)

...我们可以乐观地抽象所需的上下文:

q :: f b -> ([b] -> b) -> ([f b] -> f b)
Run Code Online (Sandbox Code Playgroud)

假设这f是一个Functor——在激励性的例子中确实如此——我们可以提升[b] -> bf [b] -> f b。如果我们有一个看起来很像 的 type 函数[f b] -> f [b],我们就可以从它得到所需的类型sequence

f考虑is 的情况((->) a):给定一个函数[b] -> b和一个 list [a -> b],我们可以返回一个函数a -> b,该函数将其 type 参数应用于a列表中的每个函数,使用选择器函数,然后返回 type 的结果b。这听起来就是你所追求的!

不幸的是,它不适用于您的特定示例 -Monad涉及的是 writer monad,它将添加一个Monoid约束并始终返回列表中a每个值的幺半群总和。a

它失败的原因是我们只有一个不透明的b值选择函数,必须在没有任何上下文的情况下使用它,这需要使用诸如sequence提取(并在过程中合并)所有单独上下文之类的东西。要编写所需的函数,您需要一种方法来合并上下文,而不会丢失将上下文与每个元素关联的信息。

reader monad 可以工作,而其他人则不能工作,因为所涉及的“合并”过程是独特的——将单个参数应用于多个函数是基于 和 给出的规范 comonoid 的逆变使用\x -> ()\x -> (x, x)其中每个结果元素唯一地确定原始输入。

为了在协变位置获得相同的属性,我们需要一个幺半群,其中每个输入元素唯一地确定结果总和,这意味着每个输入必须相同,这意味着它们必须是只有一个值的类型。基于此,我们确实可以编写一个类型稍微受限制的函数版本:

q' :: ([b] -> b) -> ([((), b)] -> ((), b))
Run Code Online (Sandbox Code Playgroud)

但我想这并不是很令人满意。:]