簡體   English   中英

Haskell在Agda的Arrow-Class和 - >在Agda

[英]Haskell's Arrow-Class in Agda and -> in Agda

我有兩個密切相關的問題:

首先,如何在Agda中對Haskell的Arrow類進行建模/表示?

 class Arrow a where 
      arr :: (b -> c) -> a b c
      (>>>) :: a b c -> a c d -> a b d
      first :: a b c -> a (b,d) (c,d)
      second :: a b c -> a (d,b) (d,c)
      (***) :: a b c -> a b' c' -> a (b,b') (c,c')
      (&&&) :: a b c -> a b c' -> a b (c,c')

(以下博客文章指出它應該是可能的......)

其次,在Haskell中, (->)是一等公民,只是另一個高階類型,它直接定義(->)作為Arrow類的一個實例。 但在阿格達怎么樣? 我可能錯了,但我覺得,Agdas ->是Agda的一個不可或缺的部分,而不是Haskell的-> 那么,Agdas可以->被視為一個更高階的類型,即一個類型函數產生Set ,它可以成為Arrow一個實例?

類型類通常被編碼為Agda中的記錄,因此您可以將Arrow類編碼為如下所示:

open import Data.Product -- for tuples

record Arrow (A : Set → Set → Set) : Set₁ where
  field  
    arr    : ∀ {B C} → (B → C) → A B C
    _>>>_  : ∀ {B C D} → A B C → A C D → A B D
    first  : ∀ {B C D} → A B C → A (B × D) (C × D)
    second : ∀ {B C D} → A B C → A (D × B) (D × C)
    _***_  : ∀ {B C B' C'} → A B C → A B' C' → A (B × B') (C × C')
    _&&&_  : ∀ {B C C'} → A B C → A B C' → A B (C × C')

雖然您不能直接引用函數類型(類似_→_語法不是有效的),但您可以為它編寫自己的名稱,然后在編寫實例時可以使用它:

_=>_ : Set → Set → Set
A => B = A → B

fnArrow : Arrow _=>_  -- Alternatively: Arrow (λ A B → (A → B)) or even Arrow _
fnArrow = record
  { arr    = λ f → f
  ; _>>>_  = λ g f x → f (g x)
  ; first  = λ { f (x , y) → (f x , y) }
  ; second = λ { f (x , y) → (x , f y) }
  ; _***_  = λ { f g (x , y) → (f x , g y) }
  ; _&&&_  = λ f g x → (f x , g x)
  }

雖然hammar的答案是Haskell代碼的正確端口,但_=>_的定義與->相比太有限,因為它不支持依賴函數。 在調整Haskell中的代碼時,如果要將抽象應用於可以在Agda中編寫的函數,那么這是一個標准的必要更改。

此外,根據標准庫的通常慣例,這個類型類將被稱為RawArrow因為要實現它,您不需要提供證明您的實例滿足箭頭定律; 有關其他示例,請參閱RawFunctor和RawMonad(注意:在0.7版本的標准庫中,Functor和Monad的定義無處可見)。

這是一個更強大的變體,我用Agda 2.3.2和0.7標准庫(也應該在0.6版本上工作)編寫和測試。 請注意,我只更改了RawArrow參數的類型聲明和_=>_ ,其余部分未更改。 但是,在創建fnArrow時,並非所有替代類型聲明都像以前一樣工作。

警告:我只檢查了代碼類型檢查和那個=>可以合理使用,我沒有檢查是否使用RawArrow檢查的示例。

module RawArrow where

open import Data.Product --actually needed by RawArrow
open import Data.Fin     --only for examples
open import Data.Nat     --ditto

record RawArrow (A : (S : Set) → (T : {s : S} → Set) → Set) : Set₁ where
  field  
    arr    : ∀ {B C} → (B → C) → A B C
    _>>>_  : ∀ {B C D} → A B C → A C D → A B D
    first  : ∀ {B C D} → A B C → A (B × D) (C × D)
    second : ∀ {B C D} → A B C → A (D × B) (D × C)
    _***_  : ∀ {B C B' C'} → A B C → A B' C' → A (B × B') (C × C')
    _&&&_  : ∀ {B C C'} → A B C → A B C' → A B (C × C')

_=>_ : (S : Set) → (T : {s : S} → Set) → Set
A => B = (a : A) -> B {a}

test1 : Set
test1 = ℕ => ℕ
-- With → we can also write:
test2 : Set
test2 = (n : ℕ) → Fin n
-- But also with =>, though it's more cumbersome:
test3 : Set
test3 = ℕ => (λ {n : ℕ} → Fin n)
--Note that since _=>_ uses Set instead of being level-polymorphic, it's still
--somewhat limited. But I won't go the full way.

--fnRawArrow : RawArrow _=>_
-- Alternatively:
fnRawArrow : RawArrow (λ A B → (a : A) → B {a})

fnRawArrow = record
  { arr    = λ f → f
  ; _>>>_  = λ g f x → f (g x)
  ; first  = λ { f (x , y) → (f x , y) }
  ; second = λ { f (x , y) → (x , f y) }
  ; _***_  = λ { f g (x , y) → (f x , g y) }
  ; _&&&_  = λ f g x → (f x , g x)
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM