2013-02-02 57 views
3

我正在學習如何使用名爲Reactive Banana的Haskell FRP庫,並且對於Haskell來說也是相當新穎的。 目前我正在創建一個將網絡作爲參數的函數,並且在函數體中編譯網絡並通過其事件循環之前進行一些初始化,但是我遇到了Haskell無法推斷出我正在嘗試的問題去做。Haskell無法從上下文中推導(t〜t1)

下面的代碼

{-# LANGUAGE ScopedTypeVariables #-} 

module Main where 
import qualified Reactive.Banana as R 
import qualified Reactive.Banana.Frameworks as RF 

main = start setupNetwork 

start :: forall t. RF.Frameworks t => R.Moment t() -> IO() 
start network = do 
    net <- RF.compile $ network 
    RF.actuate net 

keyAddHandler = RF.newAddHandler 

setupNetwork :: forall t. RF.Frameworks t => R.Moment t() 
setupNetwork = do 
    (addKey, firekey) <- RF.liftIO keyAddHandler 
    return() 

確切的錯誤,我得到的是這樣的簡化版本。

Test.hs:11:25: 
Could not deduce (t ~ t1) 
from the context (RF.Frameworks t) 
    bound by the type signature for 
      start :: RF.Frameworks t => R.Moment t() -> IO() 
    at Test.hs:(10,1)-(12,18) 
or from (RF.Frameworks t1) 
    bound by a type expected by the context: 
      RF.Frameworks t1 => R.Moment t1() 
    at Test.hs:11:12-31 
    `t' is a rigid type variable bound by 
     the type signature for 
     start :: RF.Frameworks t => R.Moment t() -> IO() 
     at Test.hs:10:1 
    `t1' is a rigid type variable bound by 
     a type expected by the context: RF.Frameworks t1 => R.Moment t1() 
     at Test.hs:11:12 
Expected type: R.Moment t1() 
    Actual type: R.Moment t() 
In the second argument of `($)', namely `network' 
In a stmt of a 'do' block: net <- RF.compile $ network 

搜索互聯網使我相信,在啓動功能的框架,並在setupNetwork功能框架之間的類型不屬於同一類型。

有無論如何讓類型匹配嗎?

回答

3

它是因爲我已經有反應香蕉(或其他任何推式系統這麼多)玩耍了一段時間,但我覺得類型簽名應該是更像

start :: (forall t. RF.Frameworks t => R.Moment t()) -> IO() 

(即你需要在正確的地方添加圓括號。)

你還需要{-# LANGUAGE RankNTypes #-}

+0

這讓事情重新編譯!在附註中,是否使用像rank2types和scopedtypevariables這樣的編譯器標誌被認爲是不好的形式? – chanko08

+1

這取決於擴展名。如果你需要'Rank2Types',那麼就不需要繞過它:你必須使用它。另一方面,'ScopedTypeVariables'並不總是絕對必要的,有些人會說你應該避免它...但總的來說,我認爲如果讓代碼更清晰,人們會說使用它。 – dave4420

+0

@ chanko08雖然我聽說'Rank2Types'正逐漸被淘汰,轉而支持'RankNTypes',所以請使用它。 – dave4420

相關問題