Haskell中的类型类-当选择的类型不';没关系吧?
这是一个关于在Haskell中使用类型类的问题 我在尝试编译代码时(下面和下面)出现了一个错误(下面) ) 作为一个刚刚学习Haskell的人,我试着听从GHC的建议, 但我认为原因是不同的 我认为问题在于“IO字符串”或“普通”类型 “String”可以是“lhello->>lbracket”类型,但GHC不是 知道是哪个 问题是这没关系,任何一种都可以 我已将代码的工作版本发布在 . 这将使用新的(非类型类)替换其中一个->>运算符 运算符'->>>>,强制“lhello->lbracket”为“IO”类型 字符串'Haskell中的类型类-当选择的类型不';没关系吧?,haskell,typeclass,Haskell,Typeclass,这是一个关于在Haskell中使用类型类的问题 我在尝试编译代码时(下面和下面)出现了一个错误(下面) ) 作为一个刚刚学习Haskell的人,我试着听从GHC的建议, 但我认为原因是不同的 我认为问题在于“IO字符串”或“普通”类型 “String”可以是“lhello->>lbracket”类型,但GHC不是 知道是哪个 问题是这没关系,任何一种都可以 我已将代码的工作版本发布在 . 这将使用新的(非类型类)替换其中一个->>运算符 运算符'->>>>,强制“lhello->lbracke
- 我的分析正确吗?还是这里发生了什么事
- 有没有办法告知GHC“lhello->”的类型 lbracket‘不要紧,那就是你应该选择其中一个 有两种可能性。或者也许有一种语言选择可以让 me指定“类的最新声明匹配实例wins” 如果有什么还没决定的话
chris@chris-linux-desktop:~/nonworkspace/haskell-sandbox$ ghc
not_working_but_clean.hs
not_working_but_clean.hs:40:16:
No instance for (Stream (IO String) (IO String) (IO String) d)
arising from a use of '->>' at not_working_but_clean.hs:40:16-34
Possible fix:
add an instance declaration for
(Stream (IO String) (IO String) (IO String) d)
In the first argument of '(->>)', namely 'lhello ->> lbracket'
In the second argument of '($)', namely
'lhello ->> lbracket ->> putStrLn'
In a stmt of a 'do' expression:
forkIO $ lhello ->> lbracket ->> putStrLn
not_working_but_clean.hs:40:16:
No instance for (Stream d String (IO ()) (IO ()))
arising from a use of `->>' at not_working_but_clean.hs:40:16-47
Possible fix:
add an instance declaration for (Stream d String (IO ()) (IO ()))
In the second argument of `($)', namely
`lhello ->> lbracket ->> putStrLn'
In a stmt of a 'do' expression:
forkIO $ lhello ->> lbracket ->> putStrLn
In the expression:
do { forkIO $ (bracket $ hello) ->> putStrLn;
forkIO $ lhello ->> lbracket ->> putStrLn;
forkIO $ bracket hello ->> putStrLn;
forkIO $ lbracket lhello ->> putStrLn;
.... }
不工作,但清洁。hs:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
TypeSynonymInstances, OverlappingInstances #-}
{-# OPTIONS_GHC #-}
module Main (
main
)
where
import Control.Concurrent (forkIO, MVar, newEmptyMVar, putMVar,
takeMVar, ThreadId, threadDelay)
import Control.Monad (forever, liftM)
class Stream a b c d where
(->>) :: a -> (b -> c) -> d
instance Stream (IO d) d (IO c) (IO c) where
f ->> g = f >>= g
instance Stream d d (IO c) (IO c) where
f ->> g = g f
instance Stream d d c c where
x ->> y = y $ x
-- This simply wraps a string in brackets.
bracket :: String -> String
bracket x = "(" ++ x ++ ")"
lbracket :: IO String -> IO String
lbracket x = liftM bracket x
hello :: String
hello = "Hello World!"
lhello :: IO String
lhello = do return hello
main :: IO ()
main = do
forkIO $ (bracket $ hello) ->> putStrLn
forkIO $ lhello ->> lbracket ->> putStrLn
forkIO $ bracket hello ->> putStrLn
forkIO $ lbracket lhello ->> putStrLn
threadDelay 10000000 -- Sleep for at least 10 seconds before exiting.
正在工作但不丑。hs:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
TypeSynonymInstances, OverlappingInstances #-}
{-# OPTIONS_GHC #-}
module Main (
main
)
where
import Control.Concurrent (forkIO, MVar, newEmptyMVar, putMVar,
takeMVar, ThreadId, threadDelay)
import Control.Monad (forever, liftM)
class Stream a b c d where
(->>) :: a -> (b -> c) -> d
instance Stream (IO d) d (IO c) (IO c) where
f ->> g = f >>= g
instance Stream d d (IO c) (IO c) where
f ->> g = g f
instance Stream d d c c where
x ->> y = y $ x
x ->>> y = y $ x
-- This simply wraps a string in brackets.
bracket :: String -> String
bracket x = "(" ++ x ++ ")"
lbracket :: IO String -> IO String
lbracket x = liftM bracket x
hello :: String
hello = "Hello World!"
lhello :: IO String
lhello = do return hello
main :: IO ()
main = do
forkIO $ (bracket $ hello) ->> putStrLn
forkIO $ lhello ->>> lbracket ->> putStrLn
forkIO $ bracket hello ->> putStrLn
forkIO $ lbracket lhello ->> putStrLn
threadDelay 10000000 -- Sleep for at least 10 seconds before exiting.
不,没有办法让GHC抛硬币然后挑一个 所有实例的类型“c”都与类型“d”相同,因此您可能会忽略类型“d”,并在定义流时重用类型“c”
instance Stream d d (IO c) (IO c) where
f ->> g = g f
instance Stream d d c c where
x ->> y = y $ x
以上都是一样的。“gf”和“y$x”是相同的。那么,为什么会有两种不同的情况呢?不,没有办法让GHC抛硬币并挑一个 所有实例的类型“c”都与类型“d”相同,因此您可能会忽略类型“d”,并在定义流时重用类型“c”
instance Stream d d (IO c) (IO c) where
f ->> g = g f
instance Stream d d c c where
x ->> y = y $ x
以上都是一样的。“gf”和“y$x”是相同的。那么为什么会有两个不同的实例呢?当我看到类型类有多个完全独立的类型参数时,我感到害怕。从一个简单的忽略来看,我会说c依赖于b,d总是和c一样。也许可以尝试使用适当的函数依赖项和一种更少的类型,也许事情会变得更容易。编辑:b似乎也依赖于a@lngoa和b的类型几乎相同,它们被限制为:a==b | | IO a==b | | a==IO b。c和d具有相同的约束。我不知道如何在Haskell中形成这个约束。正如您所注意到的,没有函数依赖关系的多参数类型类只是自找麻烦。当我看到有多个完全独立的类型参数的类型类时,我感到害怕。从一个简单的忽略来看,我会说c依赖于b,d总是和c一样。也许可以尝试使用适当的函数依赖项和一种更少的类型,也许事情会变得更容易。编辑:b似乎也依赖于a@lngoa和b的类型几乎相同,它们被限制为:a==b | | IO a==b | | a==IO b。c和d具有相同的约束。我不知道如何在Haskell中形成这个约束。正如您所注意到的,没有函数依赖关系的多参数类型类只是自找麻烦。是的,这两个实例是一个疏忽。第二个就足够了。是的,这两个例子都是疏忽。第二个就足够了。