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