2017-07-24 40 views
1

在Haskell我們可以寫這樣的代碼:哈斯克爾適用函子在F#

如何做同樣的事情在F#?

我試着寫代碼這樣的事情,但它不是同一

let (<*>) f v = 
    match v with 
    | Some v' -> 
     match f with 
     | Some f' -> Some (f' v') 
     | _ -> None 
    | _ -> None 
let cnst a _ = a 
let id = cnst <*> cnst // but it seems impossible 
let id' x = (Some (cnst x)) <*> (Some(cnst x x)) // it works 

但是在Haskell id::b->b,在F#id:'a->'a Option

我做什麼了?如何達到相同的結果?

PS:正如我所知道的一個Applicative,我們的值被包裝在一個上下文中,就像函數和函數也被包裝在上下文中一樣!

Some((+)3) and Some(2) 

在這種情況下,上下文是選項

而且Applay方法是這樣的:

let Apply funInContext valInContext = 
    match funInContext with // unwrap function 
    | Some f -> 
     match valInContext with // unwrap value 
     | Some v -> Some(f v) // applay function on value and wrap it 
     | _ -> None 
    | _ -> None 

回答

9

我略微你的代碼試圖實現的,因爲它的類型是混淆

(a -> Maybe b) -> Maybe a -> Maybe b 

這是monad結構的綁定類型,我們通常imbue Maybe/option但如果您嘗試使用我們在Haskell中的函數的應用程序實例,則它沒有任何意義。我們需要改變兩件事情,第一件事是我們需要使用函數應用程序以使代碼實現期望的效果。這應該有類型

(a -> (b -> c)) -> (a -> b) -> (a -> c) 

所以,如果我們一步最初的例子

(cnst <*> cnst) a = (cnst a) (cnst a) 
        = a 

我們可以寫爲

let (<*>) f x a = (f a) (x a) 

現在,所以我們確實有cnst <*> cnst = id的要求。

+0

謝謝,我意識到我不正確地理解'Applicatives' – kogoia