无法将预期类型“ a-> Int”与实际类型“ IOArrow String Int”匹配

时间:2019-02-28 14:56:15

标签: haskell

我试图理解箭头,并创建以下示例:

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

我在做什么错了?

1 个答案:

答案 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