4

我嘗試將traverse/sequenceA翻譯爲Javascript。現在,Haskell的實現的下面的行爲給我的麻煩:顯式類型傳遞不等於類型推斷(就表現力而言)?

traverse (\x -> x) Nothing -- yields Nothing 
sequenceA Nothing -- yields Nothing 
traverse (\x -> x) (Just [7]) -- yields [Just 7] 
sequenceA (Just [7]) -- yields [Just 7] 

作爲一個Haskell新手我不知道爲什麼第一個表達式在所有工作:

instance Traversable Maybe where 
    traverse _ Nothing = pure Nothing 
    traverse f (Just x) = Just <$> f x 

pure Nothing不應該在這種情況下工作,因爲有沒有最小的應用上下文中的價值可以放進去。看起來好像編譯器檢查這個表達式的類型懶惰,因爲映射id函數Nothing是一個noop,它只是「忽略」類型錯誤,所以說話。

這裏是我的Javascript翻譯:

(請注意,因爲Javascirpt的原型系統是不夠的一對夫婦類型的類並沒有嚴格的類型檢查,無論如何,我與教會的編碼工作,並通過類型約束功能明確。)

// minimal type system realized with `Symbol`s 

const $tag = Symbol.for("ftor/tag"); 
const $Option = Symbol.for("ftor/Option"); 

const Option = {}; 

// value constructors (Church encoded) 

const Some = x => { 
    const Some = r => { 
    const Some = f => f(x); 
    return Some[$tag] = "Some", Some[$Option] = true, Some; 
    }; 

    return Some[$tag] = "Some", Some[$Option] = true, Some; 
}; 

const None = r => { 
    const None = f => r; 
    return None[$tag] = "None", None[$Option] = true, None; 
}; 

None[$tag] = "None"; 
None[$Option] = true; 

// Traversable 

// of/map are explicit arguments of traverse to imitate type inference 
// tx[$Option] is just duck typing to enforce the Option type 
// of == pure in Javascript 

Option.traverse = (of, map) => ft => tx => 
tx[$Option] && tx(of(None)) (x => map(Some) (ft(x))); 

// (partial) Array instance of Applicative 

const map = f => xs => xs.map(f); 
const of = x => [x]; 

// helpers 

const I = x => x; 

// applying 

Option.traverse(of, map) (I) (None) // ~ [None] 
Option.traverse(of, map) (I) (Some([7])) // ~ [Some(7)] 

顯然,這種轉換從Haskell實現的偏離,因爲我得到一個[None],我應該得到一個None。老實說,這種行爲恰好與我的直覺相對應,但我認爲直覺在函數式編程中沒有幫助。現在我的問題是

  • 我只是做了一個菜鳥的錯誤?
  • 還是顯式類型傳遞不等於類型推斷(就表現力而言)?
+0

這是菜鳥的錯誤! – ftor

回答

4

GHCi不會忽略任何類型的錯誤。它默認一個不受限制的ApplicativeIO,但你只在GHCi提示符(而不是.hs源文件)中得到這種行爲。您可以檢查

> :t pure Nothing 
pure Nothing :: Applicative f => f (Maybe b) 

但仍然有

> pure Nothing 
Nothing 

你的JavaScript實現的罰款;你通過了一個Applicative實例的數組,並得到了預期的結果。

+0

如果我沒有把這麼多的工作放在這個問題上,我會笑。仍然不瞭解Haskell。謝謝! – ftor

+0

所以你說這個Traversable實例不起作用? – Bergi

+0

@Bergi不,我們只有(幸運的是!?)沒有類型默認的Javascript – ftor