Haskell 是用这个签名写函数的一种方法吗?

Haskell 是用这个签名写函数的一种方法吗?,haskell,Haskell,我有一个函数,目前正在处理特定的数据类型。我想知道我是否能成为一名将军。以下是其签名的一般版本: f :: Monad m => ((a -> b) -> c -> d) -> (a -> m b) -> m c -> m d 如果上面的内容写不出来,也许更严格的版本可以 f2 :: Monad m => ((a -> a) -> b -> b) -> (a -> m a) -> m b -> m

我有一个函数,目前正在处理特定的数据类型。我想知道我是否能成为一名将军。以下是其签名的一般版本:

f :: Monad m => ((a -> b) -> c -> d) -> (a -> m b) -> m c -> m d
如果上面的内容写不出来,也许更严格的版本可以

f2 :: Monad m => ((a -> a) -> b -> b) -> (a -> m a) -> m b -> m b

有个问题。知道
c
不会给你任何关于
a
s将被传递到
(a->b)
的信息。您要么需要能够枚举
a
s的范围,要么需要能够使用类似的方法检查提供的
a
参数

(forall f. Functor f => ((a -> f b) -> c -> f d)
在这种情况下,实现f几乎变得微不足道


一般来说,您不应该尝试实现
f
,而应该尝试将您的函数概括为
((a->b)->c->d)
,看看是否可以用镜头、遍历或类似的东西来替换它们。

不,这是不可能的,至少在没有非终止或不安全操作的情况下是不可能的

这个论点本质上类似于:我们利用
f
居住在一种我们知道无法居住的类型中

假设存在

f :: Monad m => ((a -> b) -> c -> d) -> (a -> m b) -> m c -> m d
专门化
c~()

因此

特殊化
d~a

(\g h -> f (\x _ -> g x) h (return ()))
  :: Monad m => ((a -> b) -> a) -> (a -> m b) -> m a
具体化
m~Cont t

(\g h -> runCont $ f (\x _ -> g x) (cont . h) (return ()))
  :: ((a1 -> b) -> a) -> (a1 -> (b -> r) -> r) -> (a -> r) -> r
h=const

(\g -> runCont $ f (\x _ -> g x) (cont . const) (return ()))
  :: ((r -> b) -> a) -> (a -> r) -> r
因此

因此,类型
((r->b)->r)->r
是有人居住的,因此由Curry-Howard等位主义,它对应于命题直觉逻辑的一个定理。然而,公式
((A->B)->A)->A
在这种逻辑中是不可证明的

我们得到一个矛盾,因此不存在这样的
f


相比之下,类型

f2 :: Monad m => ((a -> a) -> b -> b) -> (a -> m a) -> m b -> m b
被这个词所占据

f2 = \ g h x -> x

但我怀疑这不是你真正想要的。

到目前为止你都试过什么?你哪里有问题?你试过在Hoogle上搜索这些函数吗?
(\g -> runCont (f (\x _ -> g x) (cont . const) (return ())) id)
  :: ((r -> b) -> r) -> r
f2 :: Monad m => ((a -> a) -> b -> b) -> (a -> m a) -> m b -> m b
f2 = \ g h x -> x