haskell - 我们可以在 Haskell 中证明的类型

标签 haskell type-conversion

我们可以证明 Haskell 中涉及原生类型的同构吗?

import Prelude

newtype Leibniz a b = Leibniz {unLeibniz :: forall f. f a -> f b}


data One = One

-- `u` and `v` are inverse
u :: Bool -> Either One One
u b = if b then Right One else Left One

v :: Either One One -> Bool
v = \case
  (Left _) -> False
  (Right _) -> True

--- Can we prove proof that ?
p :: Leibniz Bool (Either One One)
p = Leibniz (\(x :: f Bool) -> __ :: f (Either One One))

最佳答案

我相信没有类型为 Leibniz Bool (Either One One) 的好术语。事实上,在某些“奇怪的”f 中我们无法进行这种转换;简单的例子是Bool :~: Bool是有人居住的,但 Bool :~: Either One One 不是,因此如果 f = (:~:) Bool 则没有 f 类型的函数Bool -> f(二选一)

但是如果你稍微修改 Leibniz:

newtype Leibniz a b = Leibniz {unLeibniz :: forall f. IsoFunctor f => f a -> f b}

这里,IsoFunctor 是一个类似于 Functor 的新类,只是它需要双向纯映射:

class IsoFunctor f where isomap :: (a -> b) -> (b -> a) -> f a -> f b

此类排除了其参数是标称而非表示的类型,如 (:~:) Bool。 (并且,在另一个方向上,总是可以为具有正确种类并且在其参数中具有代表性的类型编写实例。)然后我们可以写:

p :: Leibniz Bool (Either One One)
p = Leibniz (isomap u v)

不幸的是,编译器不(通常也不能)保证 uv 是相反的。

关于haskell - 我们可以在 Haskell 中证明的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71153806/

相关文章:

haskell - `a -> b`函数类型限制

c++ - 从隐式转换中复制构造 shared_ptr 有什么问题?

c++ - 如何在不使用对象的情况下连接字符串、整数和 float ?

go - 从 yaml 文件中删除属性

haskell - 在 Haskell 中将 "->"s 替换为 "→"s,将 "=>"s 替换为 "⇒"s 等等

haskell - 我可以将字符串切成头尾后用作整个字符串吗(:as) and using recursion on it in Haskell?

haskell - 在 Haskell 中,种类可以是星序列以外的任何东西吗?

visual-studio-2010 - 智能感知 : argument of type "_TCHAR *" is incompatible with parameter of type "const char *"

string - 将字符串序列转换为整数 (Clojure)

haskell - 在 Haskell 中创建字符串列表