簡體   English   中英

將函數表示為類型

[英]Representing Functions as Types

函數可以是高度嵌套的結構:

function a(x) {
  return b(c(x), d(e(f(x), g())))
}

首先,想知道函數是否具有instance 即,功能的評估是功能的實例。 從這個意義上說,類型是函數,實例是它的評估。 如果可以,那么如何將函數建模為類型(使用面向類型理論的語言,例如Haskell或Coq)。

幾乎就像:

type a {
  field: x
  constructor b {
    constructor c {
      parameter: x
    },
    ...
  }
}

但是我不確定我走的路是否正確。 我知道您可以說一個函數具有[返回]類型。 但是我想知道一個函數是否可以被認為是類型,如果可以的話,如何在面向類型理論的語言中將其建模為類型,並在其中對函數的實際實現進行建模。

我認為問題在於,直接基於實現的類型(我們稱它們為“ i-types”)似乎不太有用,而且我們已經有了對它們進行建模的好方法(稱為“程序”-哈哈)。

在您的特定示例中,函數的完整i類型,即:

type a {
  field: x
  constructor b {
    constructor c {
      parameter: x
    },
    constructor d {
      constructor e { 
        constructor f { 
          parameter: x 
        } 
        constructor g {
        }
    }
  }
}

只是實現本身的冗長的替代語法。 也就是說,我們可以將這種i類型編寫為(類似於Haskell的語法):

itype a :: a x = b (c x) (d (e (f x) g))

另一方面,我們可以將您的函數實現直接轉換為Haskell術語級語法,將其編寫為:

a x = b (c x) (d (e (f x) g))

i型和實現完全相同。

您將如何使用這些i型? 編譯器可以通過派生參數和返回類型來對程序進行類型檢查來使用它們。 (幸運的是,有一些著名的算法,例如Algorithm W ,可以同時從此類i-types派生和類型檢查參數和返回類型。)程序員可能不會直接使用i-types。用於重構或推理程序行為很復雜。 他們可能想要查看由編譯器派生的類型作為參數和返回類型。

特別是,在Haskell的類型級別對這些i型進行“建模”似乎沒有效果。 Haskell已經可以在術語級別對其進行建模。 只需將您的i型代碼編寫為Haskell程序即可:

a x = b (c x) (d (e (f x) g))
b s t = sqrt $ fromIntegral $ length (s ++ t)
c = show
d = reverse
e c ds = show (sum ds + fromIntegral (ord c))
f n = if even n then 'E' else 'O'
g = [1.5..5.5]

並且不要運行它。 恭喜,您已經成功為這些i型建模! 您甚至可以使用GHCi查詢派生參數和返回類型:

> :t a
a :: Floating a => Integer -> a   -- "a" takes an Integer and returns a float
>

現在,您可能正在想象,在某些情況下,實現和i-type可能會有所不同,也許是當您開始引入文字值時。 例如,也許您覺得上面的函數f

f n = if even n then 'E' else 'O'

應該被分配為類似於以下類型的類型,該類型不依賴於特定的文字值:

type f {
  field: n
  if_then_else {
    constructor even {    -- predicate
      parameter: n
    }
    literal Char          -- then-branch
    literal Char          -- else-branch
}

同樣,最好還是定義一個任意的術語級Char ,例如:

someChar :: Char
someChar = undefined

並在術語級別對此i型進行建模:

f n = if even n then someChar else someChar

同樣,只要不運行該程序,就可以成功模擬f的i類型,可以查詢其參數並返回類型,可以將其作為較大程序的一部分進行類型檢查,等等。

我不清楚您的目標是什么,所以我將嘗試指出一些您可能想閱讀的相關術語。

函數不僅具有返回類型,而且還具有描述其參數的類型。 因此, f的(Haskell)類型為“ f接受一個I​​nt和一個Float,並返回一個Floats列表”。

f :: Int -> Float -> [Float]
f i x = replicate i x

類型還可以描述函數的更多說明。 在這里,我們可能希望類型說明以下內容:列表的長度將與第一個參數相同,或者列表的每個元素將與第二個參數相同。 長度索引列表(通常稱為向量)是從屬類型的常見第一個示例。

您可能還對將類型作為參數並返回類型的函數感興趣。 這些有時稱為“類型級函數”。 在Coq或Idris中,可以使用與更熟悉的函數相同的方式來定義它們。 在Haskell中,我們通常使用Type Families或具有功能依賴項的 Type類來實現它們。

回到您的問題的第一部分,“ 減少Beta”是為每個函數參數填充具體值的過程。 我聽說有人將表達式描述為“減少后”或“完全減少”,以強調此過程中的某個階段。 這類似於“呼叫站點”功能,但強調表達式和參數,而不是周圍的上下文。

暫無
暫無

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

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