【问题标题】:Haskell Cannot deduce (t ~ t1) from the context (Frameworks t)Haskell 无法从上下文中推断出 (t ~ t1) (Frameworks t)
【发布时间】:2013-02-02 01:51:33
【问题描述】:

我正在学习如何使用名为 Reactive Banana 的 Haskell FRP 库,这对 Haskell 来说也相当新。 目前我正在创建一个将网络作为参数的函数,并在函数体中在编译网络并通过其事件循环之前进行一些初始化,但我遇到了 Haskell 无法推断出我想要的问题做。

这是代码的简化版本

{-# 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

搜索互联网使我相信 start 函数中的框架和 setupNetwork 函数中的框架之间的类型不被认为是同一类型。

有没有办法让类型匹配?

【问题讨论】:

    标签: haskell types compiler-errors frp reactive-banana


    【解决方案1】:

    我已经有一段时间没有使用响应式香蕉(或其他任何推动类型系统的东西),但我认为类型签名应该更像

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

    (即您需要在正确的位置添加括号。)

    您还需要{-# LANGUAGE RankNTypes #-}

    【讨论】:

    • 事情又开始编译了!附带说明一下,使用 rank2types 和 scopedtypevariables 等编译器标志是否被认为是不好的形式?
    • 取决于扩展名。如果您需要Rank2Types,则无法绕过它:您必须使用它。另一方面,ScopedTypeVariables 并不总是绝对必要的,有些人会说你应该避免它......但总的来说,我认为如果它使你的代码更清晰,人们会说使用它。跨度>
    • @chanko08 虽然我听说Rank2Types 正在被RankNTypes 取代,所以还是改用它吧。
    猜你喜欢
    • 2014-12-27
    • 1970-01-01
    • 2013-08-01
    • 1970-01-01
    • 2015-08-28
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多