首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell Netwire型误差

Haskell Netwire型误差
EN

Stack Overflow用户
提问于 2013-12-02 20:53:48
回答 3查看 295关注 0票数 5

我刚刚开始使用netwire,我在基本知识方面遇到了困难。

下面的代码对我来说很好:

代码语言:javascript
复制
main :: IO ()
main = testWire clockSession_ (for 3 . yeah)

yeah :: Monad m => Wire s () m a String
yeah = pure "yes"

但这并不意味着:

代码语言:javascript
复制
main :: IO ()
main = testWire clockSession_ forYeah

forYeah :: (Show b, Show e) => Wire s e Identity a b
forYeah = for 3 . yeah

失败时出错:

代码语言:javascript
复制
Could not deduce (b ~ [Char])
from the context (Show b, Show e)
bound by the type signature for
forYeah :: (Show b, Show e) => Wire s e Identity a b
  at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12-54
  `b' is a rigid type variable bound by
      the type signature for
        forYeah :: (Show b, Show e) => Wire s e Identity a b
      at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12
Expected type: Wire s e Identity a b
  Actual type: Wire s () Identity a String
In the second argument of `(.)', namely `yeah'
In the expression: for 3 . yeah
In an equation for `forYeah': forYeah = for 3 . yeah

所以我把它改成:

代码语言:javascript
复制
forYeah :: Show e => Wire s e Identity a String

这给了我一个错误:

代码语言:javascript
复制
Could not deduce (e ~ ())
from the context (Show e)
  bound by the type signature for
             forYeah :: Show e => Wire s e Identity a String
  at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12-49
  `e' is a rigid type variable bound by
      the type signature for
        forYeah :: Show e => Wire s e Identity a String
      at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12
Expected type: Wire s e Identity a String
  Actual type: Wire s () Identity a String
In the second argument of `(.)', namely `yeah'
In the expression: for 3 . yeah
In an equation for `forYeah': forYeah = for 3 . yeah

改为:

代码语言:javascript
复制
forYeah :: Wire s () Identity a String

给出以下错误:

代码语言:javascript
复制
No instance for (HasTime Integer s) arising from a use of `for'
Possible fix: add an instance declaration for (HasTime Integer s)
In the first argument of `(.)', namely `for 3'
In the expression: for 3 . yeah
In an equation for `forYeah': forYeah = for 3 . yeah

有人能解释为什么会发生这种情况,以及我如何修复我的第二个代码示例吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-12-02 21:32:19

编辑:这里有一个完整的、编译的、运行的解决方案来解决这个问题:

代码语言:javascript
复制
module Main (
    main
) where

import Prelude hiding ((.), id)
import qualified Prelude as Prelude
import Control.Wire
import Control.Wire.Interval

main :: IO ()
main = testWire clockSession_ (withoutErrors forYeah)

yeah :: Monad m => Wire s e m a String
yeah = pure "yes"

forYeah :: (Num t, HasTime t s, Monoid e, Monad m) => Wire s e m a String
forYeah = for 3 . yeah

-- This just is an easy way to specify to use () as the type for errors in testWire
withoutErrors :: Wire s () m a b -> Wire s () m a b 
withoutErrors = Prelude.id

这是最初的答案,讨论了为什么我们应该更改yeah的类型,然后对forYeah的类型进行必要的更改

yeah的类型更改为Monad m => Wire s e m a StringMonad m => (Wire s e m a)有一个Applicative实例,所以pure应该存在,而不指定yeah类型中Wire的第二个类型参数是()

注意:我不使用netwire,也没有尝试编译这个。我只看过文档中的类型。

编辑:,您可能还需要更改forYeah的类型。

Wire还有一个Category实例:

代码语言:javascript
复制
Monad m => Category (Wire s e m)

Category.操作符有以下类型:

代码语言:javascript
复制
(.) :: cat b c -> cat a b -> cat a c

因此,对于Wire来说,它是:

代码语言:javascript
复制
(.) :: Monad m => Wire s e m b c -> Wire s e m a b -> Wire s e m a c

for具有以下类型:

代码语言:javascript
复制
for :: (HasTime t s, Monoid e) => t -> Wire s e m a a

所以for 3会有一个类似于(HasTime Int s, Monoid e) => Wire s e m a a的类型。再加上‘s的Monad m => Wire s e m a String类型,for 3 . yeah的类型如下

代码语言:javascript
复制
(HasTime Int s, Monoid e, Monad m) => Wire s e m a String

因此,我们可能可以将forYeah的类型更改为:

代码语言:javascript
复制
forYeah :: (HasTime Int s, Monoid e, Monad m) => Wire s e m a String

编辑:更适合forYeah

由于整数(没有小数点)实际上等价于fromInteger的应用程序,其值为整数。fromInteger :: (Num a) => Integer -> a,文字3实际上具有Num t => t类型。因此,我们可以选择的最佳类型可能是:

代码语言:javascript
复制
forYeah :: (Num t, HasTime t s, Monoid e, Monad m) => Wire s e m a String
票数 3
EN

Stack Overflow用户

发布于 2013-12-02 21:33:33

当我将forYeah类型更改为

代码语言:javascript
复制
forYeah::Wire (Timed NominalDiffTime ()) () Identity a String

如果省略了forYeah的类型,它也会起作用。

票数 0
EN

Stack Overflow用户

发布于 2013-12-02 21:48:46

我只是问GHCi这种类型是什么:

代码语言:javascript
复制
> :m Control.Wire
> :t for (3 :: Int) . pure "yes"
for 3 . pure "yes" :: (Monad m, HasTime Int s, Monoid e) => Wire s e m a [Char]
> :{
| let forYeah :: HasTime Int s => Wire s () Identity a String
|     forYeah = for 3 . pure "yes"
| :}
> :t forYeah
forYeah :: HasTime Int s => Wire s () Identity a String

这样就行了。但是,当询问testWire clockSession_ forYeah的类型时,我会看到一个错误,它不能将NominalDiffTimeInt相匹配,但是由于NominalDiffTime也是Num的一个实例,所以只需更改签名就相当容易了:

代码语言:javascript
复制
> :{
| let forYeah :: HasTime NominalDiffTime s => Wire s () Identity a String
|     forYeah = for 3 . pure "yes"
| :}
> :t testWire clockSession_ forYeah
testWire clockSession_ forYeah :: (Applicative m, MonadIO m) => m c

所以这看起来很管用。

而且,当我将yeah分别定义为

代码语言:javascript
复制
yeah :: Monad m => Wire s () m a String
yeah = pure "yes"

forYeah :: HasTime t s => Wire s () Identity a String
forYeah = for 3 . yeah

问题似乎在HasTime约束中。由于您忽略了它,编译器将文本3默认为Integer类型,但是没有任何sHasTime Integer s实例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20337611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档