Does FuncUI really need the MSG type DU's. Can't dispatch just use functions
See original GitHub issueHere’s your counter example rewritten just using functions instead of DU’s. It removes the need for a centralised msg handler.
namespace CounterElmishSample
open System
open Avalonia.Controls
open Avalonia.Controls
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Components
open Avalonia.FuncUI.Components
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Types
open Avalonia.Layout
type CustomControl() =
inherit Control()
member val Text: string = "" with get, set
[<AutoOpen>]
module ViewExt =
()
module Counter =
open Avalonia.FuncUI.DSL
type CounterState = {
count : int
numbers: int list
}
let init = {
count = 0
numbers = [0 .. 100_000]
}
let increment state = {state with count = state.count + 1}
let decrement state = {state with count = state.count - 1}
let specific number_state = {state with count = number }
let remove_number = { state with numbers = List.except [number] state.numbers }
let view (state: CounterState) (dispatch) =
DockPanel.create [
DockPanel.children [
ListBox.create [
ListBox.items state.numbers
ListBox.itemTemplate (
TemplateView.create(fun data ->
let data = data :?> int
DockPanel.create [
DockPanel.children [
Button.create [
Button.content "delete"
Button.dock Dock.Right
Button.width 50.0
Button.tag data
Button.onClick (fun args ->
let number = (args.Source :?> Button).Tag :?> int
dispatch remove_number number
)
]
TextBlock.create [
TextBlock.text (sprintf "%A" data)
TextBlock.width 100.0
]
]
]
|> generalize
)
)
]
(*
TextBox.create [
TextBox.dock Dock.Bottom
TextBox.text (sprintf "%i" state.count)
TextBox.onTextChanged (fun text ->
printfn "new Text: %s" text
)
]
TextBlock.create [
TextBlock.dock Dock.Top
TextBlock.fontSize 48.0
TextBlock.foreground "blue"
TextBlock.verticalAlignment VerticalAlignment.Center
TextBlock.horizontalAlignment HorizontalAlignment.Center
TextBlock.text (string state.count)
]
LazyView.create [
LazyView.args dispatch
LazyView.state state.count
LazyView.viewFunc (fun state dispatch ->
let view =
TextBlock.create [
TextBlock.dock Dock.Top
TextBlock.fontSize 48.0
TextBlock.foreground "green"
TextBlock.verticalAlignment VerticalAlignment.Center
TextBlock.horizontalAlignment HorizontalAlignment.Center
TextBlock.text (string state)
]
view |> fun a -> a :> IView
)
]
*)
]
]
Is there an advantage to using the DU’s here that just plain function composition can’t do? For simple functions it is even possible to inline the operations.
Instead of
Button.onClick (fun args ->
let number = (args.Source :?> Button).Tag :?> int
dispatch remove_number number
)
you could write
Button.onClick (fun args ->
let number = (args.Source :?> Button).Tag :?> int
dispatch (fun state -> { state with numbers = List.except [number] state.numbers })
)
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Does FuncUI really need the MSG type DU's. Can't dispatch just ...
Here's your counter example rewritten just using functions instead of DU's. It removes the need for a centralised msg handler. namespace CounterElmishSample ...
Read more >fsprojects/Avalonia.FuncUI: Develop cross-plattform GUI ...
FuncUI is a thin layer built on top of AvaloniaUI. It contains abstractions for writing UI applications in different programming styles. It also...
Read more >Defunctionalisation: An underappreciated tool for writing ...
The trouble is really that defunctionalisation is much, much easier if you've got sum types, pattern-matching, and higher-order functions.
Read more >Fast single dispatch to get around multiple dispatch at ...
3) Unityper.jl is cool, but it combines types into 1, so it seems I can't write a multimethod, just different functions for each...
Read more >Functions as Redux actions - by Thai Pangsakulyanont
Redux does't like it when you dispatch a non-object into a store. So I'm going to cheat by dispatching only one action type...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I personally like the centralised approach of having an update function. I see several benefits of doing it that way:
You are also free to roll you own State & Update management. I actually do this for the drawing app you see in the screenshots. I basically have a lot of different Messages that trigger complex operations. Messages and Operations are also in a different Project and not UI dependent.
I could basically write a web version and use $(FSharp MVU Framework) without touching the Logic Project.
I did a small example of uisng FuncUI without messages. The comment I made above was done without actually trying to compile it. I’ve a fork with a change to the Counter example. Maybe it’s interesting
https://github.com/bradphelan/Avalonia.FuncUI/commit/f6de6438a3c7ea3b99d357cfe846c1d62dd5dd38
My update functions are defined
and the view is defined
I created a Binder object for managing commands and bindings. Just an experiment.