Như Hackage và/hoặc Hoogle sẽ cho bạn biết,
(>>>) :: Category k => a`k`b -> b`k`c -> a`k`c
(<<<) :: Category k => b`k`c -> a`k`b -> a`k`c
Quan sát rằng sau này là thực sự giống như
(.) :: Category k => b`k`c -> a`k`b -> a`k`c
hoặc, ở dạng Prelude
của nó, đặc biệt với Hask chủng loại chức năng,
(.) :: (b->c) -> (a->b) -> (a->c)
Vì vậy, <<<
và >>>
chỉ cần soạn các hàm, hoặc nhiều hình thái/mũi tên chung hơn.
<<<
soạn theo hướng giống như quen thuộc .
, trong khi >>>
flips các đối số để “ dữ liệu chảy từ trái sang phải ”.
Bây giờ, những gì mũi tên thành phần nghĩa, cho các thể loại khác hơn Hask, phụ thuộc của khóa học về thể loại. Kleisli IO
là dễ hiểu ví dụ: nói rằng chúng ta có một hàm thuần túy
pipe :: Double -> String
pipe = show . sqrt . (+2) . abs
Như tôi đã nói, điều này cũng có thể được viết
pipe = abs >>> (+2) >>> sqrt >>> show
Bây giờ, nếu bạn muốn thêm nguyên thủy IO đăng nhập (giống như bạn có thể bằng ngôn ngữ bắt buộc), bạn có thể giới thiệu
type (-|>) = Kleisli IO
abs', add2', sqrt' :: Num a => a -|> a
show' :: Show a => a -|> String
abs' = Kleisli $ \x -> do putStrLn ("Absolute of "++show x++"...")
return $ abs x
add2' = Kleisli $ \x -> do putStrLn ("Add 2 to "++show x++"...")
return $ x + 2
sqrt' = Kleisli $ \x -> do putStrLn ("Square root of "++show x++"...")
return $ sqrt x
show' = Kleisli $ \x -> do putStrLn ("Show "++show x++"...")
return $ show x
Với điều đó, bạn có thể xác định
pipe' :: Double -|> String
trong chính xác theo cùng một cách như trước, ví dụ:
pipe' = abs' >>> add2' >>> sqrt' >>> show'
Nhưng bây giờ bạn sẽ nhận được kết quả trung gian in ra như một tác dụng phụ.
Blog đó có [liên kết] (https://wiki.haskell.org/Arrow_tutorial#Kleisli_Arrows) đến một bài viết về Kleisli Mũi tên có vẻ hữu ích. Tôi tin rằng hai toán tử này đại diện cho một số loại thành phần hàm (cho các Mũi tên có chức năng). Đối với các loại Mũi tên khác, tôi không chắc, vì mũi tên hơi lạ với tôi. – jpaugh