我想实现应用型实例这样的类型:应用型实例 - 数据的顺序流
newtype State s a = State {runState :: s -> (a, s)}
我有(< *>)功能有些不同的想法。实现它 的一种方式。这使我的心是
(<*>) :: State s (a -> b) -> State s a -> State s b
State f <*> State s = State $ do
(fa, fs) <- f
let (sa, ss) = s fs
return (fa sa, ss)
或者
(<*>) :: State s (a -> b) -> State s a -> State s b
State f <*> State s = State $ do
(sa, ss) <- s
let (fa, fs) = f ss
return (fa sa, fs)
哪一个(或做甚至它们中的任何)是正确的,为什么呢?
他们都只是通过“状态”转换顺序进行类型检查和区分。我无法找到任何理由相对于另一个...
这个问题似乎是[nerd snipe](https://xkcd.com/356/)的成熟机会。这里有一个令人费解的(但是有效的)定义,对于一个类似于状态的monad的'>> ='你可以考虑:state f >> = g = state $ \ s - > let {(u,x) = ft; (t,y)= runState(g x)s}(u,y)'。观察'x','y'如何从上到下,但是''''''','''从底部到顶部。仍然让我的大脑受到伤害:) –
如果你还没有看到它,[你可能会喜欢这个](https://lukepalmer.wordpress.com/2008/08/10/mindfuck-the-reverse-state-monad/) – luqui
@BenjaminHodgson这是奇怪的美丽 – 4castle