解压缩存在类型的存在

时间:2018-10-29 15:54:08

标签: haskell types gadt existential-type

我尝试编写以下代码:

{-# LANGUAGE GADTs #-}

module V where

data V a where
  V :: (c -> a) -> V a

down :: V (V a) -> V a
down (V f) = V $ \(c,d) -> case f c of
  V f' -> f' d

然后,GHC回答了type variable `c' would escape its scope

我了解为什么它不能编译:它使用case 中隐藏的存在类型

但是实际上,该类型仍然被V隐藏。因此基本上我认为功能down没问题。

是否可以编写可编译的down函数?

3 个答案:

答案 0 :(得分:2)

这是一个基本问题:import json import requests delim = "," # Just in case you switch to tsv or something with open('file.csv', 'r') as file: for line in file: line_list = line.split(delim) Member_ID = line_list[0] Login_ID = line_list[1] payload = { # Or enclose this in json.dumps() "Member_ID": Member_ID, "Login_ID": Login_ID } r = requests.post("your-target-url.com", data=payload) 可以窥视f,并使用c的值来确定要在其存在中隐藏哪种类型。例如:

c

因此,如果我们叫v :: V (V Int) v = V $ \p -> case p of False -> V (id :: Int -> Int) True -> V (fromEnum :: Char -> Int) ,则d必须既是有效的Int又是有效的Char!为了能够提供可以如此变化的存在,您需要确保其参数可以采用它可能需要的所有类型。

down v

答案 1 :(得分:1)

在Haskell中,我找不到使您的代码正常工作的简单方法。

不过,我发现有趣的是,您的想法确实在具有完全依赖类型的语言中起作用,例如Coq(可能还有Agda,Idris等)。

丹尼尔·瓦格纳(Daniel Wagner)指出,主要症结在于c所产生的类型可以取决于(c,d)的值,因此原始代码中的forall a. a对应为一个依赖对

对于它的价值,这是我们如何在Coq中做到这一点。

请注意,这并不涉及像(* An existential type, under an impredicative encoding *) Inductive V (A: Type): Type := Vk : forall (B: Type), (B -> A) -> V A . (* The usual "identity to equivalence" *) Definition subst {A B: Type} (p: A = B) (x: A): B := match p with | eq_refl => x end . (* The main function. Essentially, we want to turn Vk B (fun b => Vk C g) into Vk (B*C) (fun (b,c) => g c) but both C and g can depend on (b:B), so (B*C) should be a Sigma type {b:B & ty b}. *) Definition down (A: Type) (x: V (V A)): V A := match x with | Vk B f => let ty (z: V A): Type := match z with | Vk C g => C end in Vk A {b:B & ty (f b)} (fun w => match w with | existT b y => match f b as o return ty (f b) = ty o-> A with | Vk C g => fun (h: ty (f b) = C) => g (subst h y) end eq_refl end ) end . 这样的无人居住类型。

{{1}}

答案 2 :(得分:1)

感谢您做出一个很好的回答,爱!

我重写了Agda的代码,实际上它可以编译。作为上述答案的补充说明,我将代码放在这里。

module down where

open import Level
open import Data.Product

data V {ℓ} (A : Set ℓ) : Set (suc ℓ) where
  Vk : {B : Set} → (B → A) → V A

down : ∀ {ℓ} {A : Set ℓ} → V (V A) → V A
down {ℓ} {A} (Vk {B} f) = Vk go where
  ty : V A → Set
  ty (Vk {C} _) = C
  go : Σ B (λ b → ty (f b)) → A
  go (b , c) with f b
  go (b , c) | Vk {C} g = g c