国家单子,为什么不一个元组?单子、国家

2023-09-03 02:01:22 作者:若白.

我刚刚完成我的头周围单子(至少我想,认为我有),更具体的状态单子,其中有些人是聪明的方式,然后我想通了,所以我的方式可能这个问题。

总之,国家单子通常与M&LT实施;一>因为这样的事情(F#):

 键入国家<一,国家> =的状态(状态 - >A *状态)
 

现在我的问题:是否有任何理由,为什么你不能用一个元组吗?其他然后 MonadA℃之间可能的歧义;A,B> MonadB<一个,B> 这既能成为相当于('A *'B)元组。

编辑:为了清楚起见,增加了例如的

 键入StateMonad()=
  构件m.Return一个=(乐趣秒 - >一种,多个)
  会员m.Bind(X,F)=(有趣的S  - >让,S_ =在发S_ XS)

让状态=新StateMonad()
我们的getState =(有趣的S  - > S,S)
让我们的setState S =(乐趣_  - >(),S)
让执行米每秒= M S |> FST
 

解决方案

在国家单子的本质与类型状态的作品 - > 水库*状态,从而重新presents一个计算产生了一些的初始状态的,并产生结果(连同状态的新值)。

POSTAL PARCEL单子怎么填,这个日本往国内邮可以吗 大概多长时间到

如果你问它是否有什么差别,我们是否给予一些特殊的名字,以这种类型(如国家<状态,资源与GT; ),那么答案是它其实并不重要。到类型给予一定的特殊名称的唯一目的是,它使code更具可读性。例如,让我们来看看下面的例子中的两个可能的类型签名:

 让富N = {状态
  让! M =的getState()
  做!的setState第(m + 1)
  返回的sprintf结果:%D(N * M)}

//使用国家<状态,资源与GT;类型:
VAL FOO:INT  - >国家< INT,字符串>

//使用底层重新presentation:
VAL FOO:INT  - > INT  - > INT *状态
 

第一种类型签名更明确地说,我们正在写功能的一些单子。第二个例子仅仅是一个函数,它接受两个 INT 值。我觉得第一个主要好处是,你可以更容易地实现该类型可以从其他一元计算中使用(使用状态{...}书面)。

不过,正如我已经指出的,这不是一个技术要求。人们可能使用这种风格,因为很多单子都来自哈斯克尔,在单子都与键入的(如州与相关联;状态,资源与GT; ),而不是一个的的计算生成器的(如状态),所以这听起来像一个好主意,定义一个新的类型在Haskell每个单子

I've just wrapped my head around monads (at least I'd like to think I have) and more specifically the state monad, which some people that are way smarter then me figured out, so I'm probably way of with this question.

Anyway, the state monad is usually implemented with a M<'a> as something like this (F#):

type State<'a, 'state> = State of ('state -> 'a * 'state)

Now my question: Is there any reason why you couldn't use a tuple here? Other then the possible ambiguity between MonadA<'a, 'b> and MonadB<'a, 'b> which would both become the equivalent ('a * 'b) tuple.

Edit: Added example for clarity

type StateMonad() =
  member m.Return a = (fun s -> a, s)
  member m.Bind(x, f) = (fun s -> let a, s_ = x s in f a s_)

let state = new StateMonad()
let getState = (fun s -> s, s)
let setState s = (fun _ -> (), s) 
let execute m s = m s |> fst

解决方案

The State monad essentially works with a type 'state -> 'res * 'state, which represents a computation that takes some initial state and produces result (together with a new value of the state).

If you're asking whether it makes any difference whether we give some special name to this type (e.g. State<'state, 'res>) then the answer is it doesn't really matter. The only purpose of giving some special name to the type is that it makes the code more readable. For example, let's look at the two possible type signatures of the following example:

let foo n = state {
  let! m = getState()
  do! setState(m + 1)
  return sprintf "Result: %d" (n * m) }

// Using State<'state, 'res> type:
val foo : int -> State<int, string>

// Using the underlying representation:
val foo : int -> int -> int * state

The first type signature more clearly says that we're writing function in some monad. The second example is just a function that takes two int values. I think the main benefit of the first one is that you can more easily realize that the type can be used from other monadic computation (written using state { ... }).

However, as I already noted, this isn't a technical requirement. People probably use this style, because many monads come from Haskell, where monads are associated with the type (such as State<'state, 'res>) and not a computation builder (such as state), so it sounds like a good idea to define a new type for every monad in Haskell.