我试图理解箭头,并创建以下示例:
{-# LANGUAGE Arrows #-}
module Main where
import Control.Arrow
import Control.Monad
import qualified Control.Category as Cat
import Data.List
import Data.Maybe
data IOArrow a b = IOArrow { runIOArrow :: a -> IO b }
instance Cat.Category IOArrow where
id = IOArrow return
IOArrow f . IOArrow g = IOArrow $ f <=< g
instance Arrow IOArrow where
arr f = IOArrow $ return . f
first (IOArrow f) = IOArrow $ \(a, c) -> do
x <- f a
return (x, c)
foo :: Int -> String
foo = show
bar :: String -> IO Int
bar = return . read
main :: IO ()
main = do
let f = arr (++"!!") . arr foo . IOArrow bar . arr id
result <- runIOArrow f "123"
putStrLn result
编译器抱怨:
• Couldn't match expected type ‘a -> Int’
with actual type ‘IOArrow String Int’
• Possible cause: ‘IOArrow’ is applied to too many arguments
In the first argument of ‘(.)’, namely ‘IOArrow bar’
In the second argument of ‘(.)’, namely ‘IOArrow bar . arr id’
In the second argument of ‘(.)’, namely
‘arr foo . IOArrow bar . arr id’
• Relevant bindings include
f :: a -> [Char] (bound at app/Main.hs:32:7)
|
32 | let f = arr (++"!!") . arr foo . IOArrow bar . arr id
| ^^^^^^^^^^^
• Couldn't match expected type ‘IOArrow [Char] String’
with actual type ‘a0 -> [Char]’
• Probable cause: ‘f’ is applied to too few arguments
In the first argument of ‘runIOArrow’, namely ‘f’
In a stmt of a 'do' block: result <- runIOArrow f "123"
In the expression:
do let f = arr (++ "!!") . arr foo . IOArrow bar . arr id
result <- runIOArrow f "123"
putStrLn result
|
33 | result <- runIOArrow f "123"
| ^
我在做什么错了?
答案 0 :(得分:5)
您想要(.) :: Category cat => cat b c -> cat a b -> cat a c
中的Control.Category
,但最终却使用了(.) :: (b -> c) -> (a -> b) -> (a -> c)
中的Prelude
。
NoImplicitPrelude
,然后导入Prelude
,以显式隐藏id
和(.)
Control.Category
不合格(或到处遭受Cat..
)奖金:arr id
只是id
的{{1}}。
Control.Catgory