【发布时间】:2018-07-26 15:46:53
【问题描述】:
Observable 真的是一个单子吗?它是否遵守 Monad 法则 (https://wiki.haskell.org/Monad_laws)?在我看来不像这样。但也许我的理解是错误的,有人可以对这个问题有所了解。我目前的推理是(我使用 :: 来表示“是善良的”):
1) 左身份: return a >>= f ≡ f a
var func = x => Rx.Observable.of(10)
var a = Rx.Observable.of(1).flatMap(func) :: Observable
var b = func(1) :: ScalarObservable
哈斯克尔:
func = (\_ -> putStrLn "B")
do { putStrLn "hello"; return "A" } >>= func :: IO ()
func "A" :: IO ()
所以左身份不适用于 Observable。 Observable 显然不是 ScalarObservable。在 Haskell 中,类型是相同的 - IO ()。
2) 正确的身份: m >>= return ≡ m
var x = Rx.Observable.of(1);
x.flatMap(x => Observable.of(x)) :: Observable
x :: ScalarObservable
哈斯克尔:
Just 2 >>= return :: Num b => Maybe b
Just 2 :: Num a => Maybe a
与左身份相同的情况。可观察的!== ScalarObservable。而在 Haskell 中,类型保持不变,它是一个 Maybe,里面有一个 Num。
3) 关联性
(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
var x = Rx.Observable.of(10)
var func1 = (x) => Rx.Observable.of(x + 1)
var func2 = (x) => Rx.Observable.of(x + 2)
x.flatMap(func1).flatMap(func2) :: Observable
x.flatMap(e => func1(e).flatMap(func2)) :: Observable
哈斯克尔:
add2 x = Just(x + 2)
add1 x = Just(x + 1)
Just 2 >>= add1 >>= add2 :: Num b => Maybe b
Just 2 >>= (\x -> add1(x) >>= add2) :: Num b => Maybe b
这似乎是唯一适用于 Observable 的定律。 但我不知道,也许这不应该像我那样推理。你怎么看?
【问题讨论】:
-
我很确定
ScalarObservable只是Observable<Number>的优化专业化。请注意,法律并没有规定双方需要返回完全相同的值,而只是规定他们需要表现相同。 -
谢谢@Bergi,我希望得到这样的答案。最后,在wiki.haskell.org/Monad_laws 中,我们可以读到 “这里,p ≡ q 只是意味着您可以将 p 替换为 q,反之亦然,并且您的程序的行为不会改变:p 和 q 是等价物。”.这是否意味着如果我们执行
x.flatMap(x => Observable.of(x)).subscribe(a => console.log(a))和x.subscribe(a => console.log(a))并最终得到相同的副作用,那么这足以证明左身份 可以支持Observable? -
这是正确的身份,但总的来说是的
标签: javascript haskell rxjs observable