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

zer*_*ing 4 haskell arrows

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

{-# 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 
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

    • 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"
   |                        ^  
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Ale*_*lec 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从Control.Catgory.

{-# LANGUAGE Arrows, NoImplicitPrelude #-}

module Main where

import Prelude hiding ((.), id)
import Control.Arrow
import Control.Monad
import Control.Category
import Data.List
import Data.Maybe

data IOArrow a b = IOArrow { runIOArrow :: a -> IO b }

instance 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 . id
  result <- runIOArrow f "123"
  putStrLn result 
Run Code Online (Sandbox Code Playgroud)