在數學上,函式應用的二元運算是一個 endo-Functor/Monad。
pipe :: (a -> b) -> a -> b
pipe = \f -> \a -> f a
(|>) :: a -> (a -> b) -> b
(|>) = flip pipe
infixl 1 |>
它被稱為管道運算子,在 Haskell 中,預定義為
https://hackage.haskell.org/package/base-4.16.0.0/docs/Data-Function.html#v:-38-
(&) :: a -> (a -> b) -> b
monadTestPipe :: IO ()
monadTestPipe = do
"Monad Laws========" & print
let i = id
let a = (3 :: Int)
let f = (\a -> a 1) >>> i
let g = (\a -> a * 2) >>> i
let m = f a -- 4
"---------------------------------" & print
do
"-- Left/Center/Right identity" & print
let lft = a & i & f
let ctr = a & f -- = m
let rit = a & f & i
---------------------------------
lft & print -- 4
ctr & print -- 4
rit & print -- 4
"---------------------------------" & print
do
"-- Associativity" & print
-- m = f a -- 4
(m & f) & g
& print -- 10 = (4 1)x2
m & (\x -> f x & g)
& print -- 10
"---------------------------------" & print
為什么管道操作(&) :: a -> (a -> b) -> b在 Haskell 中沒有被視為(至少沒有集成)Monad?
或者,可以這么說,我從未在任何 Haskell wiki 或書籍中讀過它。
編輯:我想讓我的問題盡可能簡潔,以防止問題擴散,但是
class Applicative m => Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
>>=只是 Haskell 中 Monad 型別類的一個符號,并且&可以集成到>>=因為&是數學意義上的 monad 運算子。
return是id :: a -> a
uj5u.com熱心網友回復:
它被視為(>>=)monad(特別是 identity monad)的系結操作(aka ),而不是直接的。由于型別系統的作業方式,您必須使用包裝器:您不能將型別同義詞type Id a = a用作實體,Monad并且沒有型別級別的 lambda。
type Id a = a簡單地描述了一個同義詞:a和Id a是同一型別。
你不能有一個像
instance Monad Id
使用上面的Idbecause定義Id本質上與型別級別的 lambda 相同\a -> a(如果 Haskell 中存在這樣的東西),而Haskell 沒有這種型別級別的 lambda,因為它們會使 Haskell 的型別系統 undecidable。
newtype然而,這正是創建該構造的主要原因之一。它創建了一個新型別(顧名思義),它包裝了舊型別,并且只存在于在型別級別區分舊型別和新型別。它們甚至具有相同的運行時表示。您可以在此處閱讀有關兩者之間區別的更多資訊。
在這種情況下,包裝器稱為Identity.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/431372.html
