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)
您将其描述为想要“将函数提升到上下文中”,所以让我们看看这意味着什么。从所需的类型开始:
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] -> b
到f [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)
但我想这并不是很令人满意。:]