gpt4 book ai didi

Haskell Netwire - 类型错误

转载 作者:行者123 更新时间:2023-12-02 21:07:54 25 4
gpt4 key购买 nike

我刚刚开始使用 netwire,但在基础知识上遇到了困难。

以下代码对我来说效果很好:

main :: IO ()
main = testWire clockSession_ (for 3 . yeah)

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

但这并不:

main :: IO ()
main = testWire clockSession_ forYeah

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

失败并出现错误:

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

所以我把它改为:

forYeah :: Show e => Wire s e Identity a String

这给了我错误:

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

将其更改为:

forYeah :: Wire s () Identity a String

出现以下错误:

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

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

最佳答案

编辑:这是针对此问题的完整、可编译、可运行的解决方案:

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 应该存在,无需指定 Wire 的第二个类型参数yeah 中的 类型是 ()

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

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

Wire 还有一个 Category 实例:

Monad m => Category (Wire s e m)

Category. 运算符具有以下类型:

(.) :: cat b c -> cat a b -> cat a c

所以对于 Wire 来说是:

(.) :: Monad m => Wire s e m b c -> Wire s e m a b -> Wire s e m a c

for 具有以下类型:

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 的类型。结合 yes 的 Monad m => Wire s e m a String 类型,为 3 。是的会有这样的类型

(HasTime Int s, Monoid e, Monad m) => Wire s e m a String

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

forYeah :: (HasTime Int s, Monoid e, Monad m) => Wire s e m a String

编辑:更好的 forYeah 类型

an integer numeral (without a decimal point) is actually equivalent to an application of fromInteger to the value of the numeral as an Integer ,以及 fromInteger::(Num a) => Integer -> a,文字 3 实际上具有类型 Num t => t。因此,我们可以选择的最佳类型可能是:

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

关于Haskell Netwire - 类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20337611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com