I wrote sometime fsharp code for me, but i feel wrong that
type Inter =
abstract DoIt: string -> unit
I do not have name for string. It make hard for mind reading code.
It imposible?
public interface Inter { void DoIt(string name); }
I wrote sometime fsharp code for me, but i feel wrong that
type Inter =
abstract DoIt: string -> unit
I do not have name for string. It make hard for mind reading code.
It imposible?
public interface Inter { void DoIt(string name); }
type Inter =
abstract DoIt: name: string -> unit
let oe = { new Inter with member x.DoIt name = printfn "Doing it with %s" name }
oe.DoIt "altbodhi"
Yes, i noticed few moments later. But how to same do in record?
type Storage = { Flush : (id: int) -> unit }
If it impossible when why reason?
It does seem to be impossible. Maybe you could submit a feature request if there isn’t one already as it sounds useful to me.
This is the closest I could get to it so far.
type IdentArg = { id: int }
type Storage = {
Flush: IdentArg -> unit
}
let storage = {
Flush = fun { id = id } -> printfn "Flushing %d" id
}
storage.Flush { id = 42 }
I’ve heard that records of functions are slightly discouraged over interfaces, since interfaces have features that aren’t supported by records of functions. You’ve highlighted one of those features. Another one is having a generic function in a non-generic interface. I can have
> type Printer =
- abstract member print: 'a -> string;;
type Printer =
abstract print: 'a -> string
> let shouter = { new Printer with member this.print(x) = (string x).ToUpper() };;
val shouter: Printer
> let fn (x: Printer) =
- printfn "%s" (x.print [ "Hey there"; "How are you?" ])
- printfn "%s" (x.print {| Message = "Hey there" |});;
val fn: x: Printer -> unit
> fn shouter;;
[HEY THERE; HOW ARE YOU?]
{ MESSAGE = "HEY THERE" }
val it: unit = ()
You can’t do the same with a record of functions:
> type PrinterRecord = { print: 'a -> string };;
type PrinterRecord = { print: 'a -> string };;
------------------------------^^
/workspace/stdin(7,31): error FS0039: The type parameter 'a is not defined.
The best you can get is
> type PrinterRecord<'a> = { print: 'a -> string };;
type PrinterRecord<'a> =
{ print: ('a -> string) }
> let fnRec (listPrinter: PrinterRecord<_>) (recordPrinter: PrinterRecord<_>) =
- printfn "%s" (listPrinter.print [ "Hey there"; "How are you?" ])
- printfn "%s" (recordPrinter.print {| Message = "Hey there" |});;
val fnRec:
listPrinter: PrinterRecord<string list> ->
recordPrinter: PrinterRecord<{| Message: string |}> -> unit
> fnRec { print = fun x -> (string x).ToUpper() } { print = fun x -> (string x).ToUpper() };;
[HEY THERE; HOW ARE YOU?]
{ MESSAGE = "HEY THERE" }
val it: unit = ()
which is a lot less helpful because you need a PrinterRecord for each concrete type you need to work with. So I think the advice from the F# folks is to prefer interfaces to records when you’re needing structures containing functions.
named argument is matter, maybe more than type, because if args count is more than one it hard for means about data. But data control logic. I want simple way to define type member as full function as is:
let member (id:int, name:string) = ()
// and call with them names
member (id = 1, name = "Alice" )
> type Person (id, name) = class end;;
type Person =
new: id: obj * name: obj -> Person
> Person;;
val it: id: 'a * name: 'b -> Person
like this. For example in calc scalar of vector order points is matter.
One way Alias:
> type name = string;;
type name = string
> type Printer = { print: name -> unit };;
type Printer =
{ print: (name -> unit) }
> let printer = { print = printfn "%s" };;
val printer: Printer = { print = <fun:printer@17> }
> printer.print;;
val it: (name -> unit) = <fun:printer@17>
> printer.print "OK";;
OK
val it: unit = ()
But I see name arg without real type