是用这种签名编写函数的方法吗?

时间:2017-11-18 07:16:42

标签: 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 b

2 个答案:

答案 0 :(得分:4)

不,这是不可能的,至少没有非终止或不安全的操作。

这个论点与this one基本相似:我们利用f来居住一种我们知道无法居住的类型。

假设存在

f :: Monad m => ((a -> b) -> c -> d) -> (a -> m b) -> m c -> m d

专业化c ~ ()

f :: Monad m => ((a -> b) -> () -> d) -> (a -> m b) -> m () -> m d

因此

(\g h -> f (\x _ -> g x) h (return ()))
  :: Monad m => ((a -> b) -> d) -> (a -> m b) -> m d

Speciazlize d ~ a

(\g h -> f (\x _ -> g x) h (return ()))
  :: Monad m => ((a -> b) -> a) -> (a -> m b) -> m a

Speclialize 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

因此

(\g -> runCont (f (\x _ -> g x) (cont . const) (return ())) id)
  :: ((r -> b) -> r) -> r

因此,类型((r -> b) -> r) -> r是有人居住的,因此通过库里 - 霍华德同构主义,它对应于命题直觉主义逻辑的定理。但是,公式((A -> B) -> A) -> APeirce's law,已知在这种逻辑中不可证明。

我们得到了矛盾,因此没有f

相比之下,类型

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

居住在

这个词中
f2 = \ g h x -> x

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

答案 1 :(得分:2)

有一个问题。了解c并未向您提供有关哪些a将传递给(a -> b)的任何信息。您需要能够枚举a的Universe,或者能够使用

之类的内容检查所提供的a参数
(forall f. Functor f => ((a -> f b) -> c -> f d)

在这种情况下,实现f几乎是微不足道的。

除了尝试实施f之外,您应该尝试概括((a -> b) -> c -> d)之类的功能,看看是否可以用镜头,遍历或类似的东西替换它们。