6 people like it.
Like the snippet!
Example of Elm-like immutable MVVM
An example of a simple ViewModel for WPF inspired by the "immutable" Elm Architecture - http://elm-lang.org/.
It is just an proof of concept.
See the library code and a few working examples at https://github.com/Zdenek-Pavlis/impF
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
|
open impF.VmBase
module Person =
type Model =
{ FirstName : string
; LastName : string
; IsSwapped : bool
}
with
member x.FullName =
sprintf "%s %s" x.FirstName x.LastName
member x.IsNotSwapped =
not x.IsSwapped
type Msg =
| First of string
| Last of string
| Swap
| SwapBack
let init =
{ FirstName = ""
; LastName = ""
; IsSwapped = false
}
let update msg state =
let swap () =
{ IsSwapped = not state.IsSwapped
; FirstName = state.LastName
; LastName = state.FirstName
}
match msg with
| First s ->
{ state with FirstName = s }
| Last s ->
{ state with LastName = s }
| Swap ->
swap()
| SwapBack ->
swap()
type PersonVm(p) =
let sm =
stateManager Person.update p
member val FirstName =
sm.Field Person.Msg.First (fun m -> m.FirstName)
member val LastName =
sm.Field Person.Msg.Last (fun m -> m.LastName)
member val FullName =
sm.RoField (fun m -> m.FullName)
member val SwapCommand =
sm.Command Person.Msg.Swap (fun m -> m.IsNotSwapped)
member val SwapBackCommand =
sm.Command Person.Msg.SwapBack (fun m -> m.IsSwapped)
module VmFactory =
let newVm () =
createRootVm PersonVm Person.init
|
namespace impF
module VmBase
from impF
type Model =
{FirstName: string;
LastName: string;
IsSwapped: bool;}
member FullName : string
member IsNotSwapped : bool
Full name: Script.Person.Model
Model.FirstName: string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
Model.LastName: string
Model.IsSwapped: bool
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
val x : Model
member Model.FullName : string
Full name: Script.Person.Model.FullName
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
member Model.IsNotSwapped : bool
Full name: Script.Person.Model.IsNotSwapped
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
type Msg =
| First of string
| Last of string
| Swap
| SwapBack
Full name: Script.Person.Msg
union case Msg.First: string -> Msg
union case Msg.Last: string -> Msg
union case Msg.Swap: Msg
union case Msg.SwapBack: Msg
val init : Model
Full name: Script.Person.init
val update : msg:Msg -> state:Model -> Model
Full name: Script.Person.update
val msg : Msg
val state : Model
val swap : (unit -> Model)
val s : string
Multiple items
type PersonVm =
new : p:VmStateManagerParams<Model> -> PersonVm
member FirstName : Field<string>
member FullName : ReadOnlyField<string>
member LastName : Field<string>
member SwapBackCommand : ImmutableCommand
member SwapCommand : ImmutableCommand
Full name: Script.PersonVm
--------------------
new : p:VmStateManagerParams<Person.Model> -> PersonVm
val p : VmStateManagerParams<Person.Model>
val sm : VmStateManager<Person.Msg,Person.Model>
val stateManager : update:('a -> 'state -> 'state) -> p:VmStateManagerParams<'state> -> VmStateManager<'a,'state> (requires equality)
Full name: impF.VmBase.stateManager
module Person
from Script
val update : msg:Person.Msg -> state:Person.Model -> Person.Model
Full name: Script.Person.update
member IVmStateManager.Field : msgBuilder:('fieldState -> 'msg) -> fieldStateSelector:('state -> 'fieldState) -> Field<'fieldState> (requires equality and equality)
union case Person.Msg.First: string -> Person.Msg
val m : Person.Model
Person.Model.FirstName: string
union case Person.Msg.Last: string -> Person.Msg
Person.Model.LastName: string
member IVmStateManager.RoField : fieldStateSelector:('state -> 'fieldState) -> ReadOnlyField<'fieldState> (requires equality and equality)
property Person.Model.FullName: string
member IVmStateManager.Command : msg:'msg -> canExecuteSelector:('state -> bool) -> ImmutableCommand (requires equality)
union case Person.Msg.Swap: Person.Msg
property Person.Model.IsNotSwapped: bool
union case Person.Msg.SwapBack: Person.Msg
Person.Model.IsSwapped: bool
module VmFactory
from Script
val newVm : unit -> PersonVm
Full name: Script.VmFactory.newVm
val createRootVm : factory:(VmStateManagerParams<'vmState> -> 'vm) -> init:'vmState -> 'vm
Full name: impF.VmBase.createRootVm
val init : Person.Model
Full name: Script.Person.init
More information