2015-06-30 106 views
3

我知道標題是有點不清楚,問題是:如何撰寫這兩個功能

假設我有a -> c類型的函數,b -> d類型的其他功能,如何才能得到(a -> b) -> (c -> d)類型的函數,還是一般不可能?


也許我應該提供一些背景知識。我問了這個問題,因爲我無法從論文Fun with phantom types解決練習9。

data Type t where 
    ... 
    RFun :: Type a -> Type b -> Type (a -> b) 

而且tequal功能

tequal :: Type t -> Type u -> Maybe (t -> u) 
... 
tequal (RFun a b) (RFun c d) = -- should do something with (tequal a c) (tequal b d) 

所以,問題歸結爲撰寫a -> cb -> d得到(a -> b) -> (c -> d)

+0

那是什麼?一個具有函數和返回函數的函數?你真的意思是第一個參數是(a - > b)嗎? – m0nhawk

+0

是的,它是一個函數,它接受一個函數並返回另一個函數,只需從該類型中讀取即可。 –

+0

只是由此產生的類型是完全沒有意義的,因爲你有一些不同的功能。 – m0nhawk

回答

3

這是不可能的。

假設你想要的功能f :: (a -> b) -> (c -> d)

您可以將其類型簡化爲(a -> b) -> c -> d(請參閱why)。

f如何實現?它有a -> b類型的第一個參數,第二c類型:

f ab c = ... 

你可以用ab做什麼?這是一種功能,但由於您沒有任何類型的a_|_除外),所以無法應用它。即使你有功能g :: a -> ch :: b -> d他們是沒有用的,因爲你沒有任何類型的ab,你不能編寫它們。

所以,唯一有效的實現是一樣的東西

f ab = undefined 

f = undefined 

關於你問題的第二部分,似乎可以遞歸使用tequal檢查功能類型平等:類型a -> cb -> d只有等於a = bc = d(這是有效的,因爲紙張中的玩具類型系統沒有類型變量)。

下面是執行的草圖:

tequal (RFun a c) (RFun b d) 
    = liftM2 func (tequal a b) (tequal c d) 

你可以注意到,代碼幾乎是相同的RPair的情況。這與Currying有關。

0

我相信你正在尋找高階函數,這基本上是一個函數作爲參數或返回其他函數。

例如以示出一個高階函數,可以定義以下功能:

f0 :: Int -> Int 
f0 x = 0 

f1 :: a -> a 
f1 x = x 

f2 :: (a -> a) -> a -> a 
f2 f a = f(a) 

f3 :: (a -> a) -> (a -> a) 
f3 f = f1 

注意,F2取功能並將其應用到該第二參數和F3需要功能返回函數f1。

如果你執行f2(f3(f0))5,它會返回5給你。

步驟一步

1- F2(F3(F0))5 F3取一個函數(F0),並返回F1。

2- F2(F1)5 F2取一個函數(F1)和它適用於(5)

3- F1(5) f1被施加到5

第二參數
+0

我對高階函數非常熟悉。我的問題是如何按照我通過類型指定的方式來編寫它們。不管怎麼說,還是要謝謝你! –

+0

我明白了。我在編輯答案之前就開始寫作了,這裏我的不好。我正在尋找其他方式來解決這個問題。 – Xaphanius

3

作爲一個小補充到最大taldykin的回答,

鑑於

f :: (a -> c) -> (b -> d) -> (a -> b) -> (c -> d) 
f ac bd ab = ??? 

沒什麼上ly一種方法來結合參數

bd . ab :: a -> d 

但現在我們卡住了!我們無法從a -> c,b -> d,a -> ba -> d的任意組合構建c -> d

在另一方面,如果我們有一個c -> a那麼我們就可以構造一個

f :: (c -> a) -> (b -> d) -> (a -> b) -> (c -> d) 
f ca bd ab = bd . ab . ca 

順便說一句,它可以是非常有幫助的得到了筆和紙,畫了一些箭頭並嘗試連接它們變成圖:

如果你試圖爲f :: (a -> c) -> (b -> d) -> (a -> b) -> (c -> d)做同樣的,然後你會看到,有沒有辦法得出連接c -> d圖:

enter image description here

,現在我們也沒有辦法連接點。