F # assign (custom) function type

For all the progress made in F #, I'm still lost in the various syntaxes of the constructor and deconstructor.

I am running recursive modeling. One parameter is the stop condition function. I have various possible stopping conditions to choose from. I make them all have the same signature. Therefore, I decided that it would be nice to form in order to block these functions to a user type - so that you can send not only any function that matches the signature:

type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool) 

I think I'm doing it right, from textbooks having a type name and an identical constructor name (confusing ...), for the only case, a discredited union. But now I can’t figure out how to apply this type to a real function:

let Condition1 lastRet nextRet i fl =
    true

How do I make condition 1 of type StoppingCondition? I bet it's trivial. But I tried to put StoppingCondition as the first, second or last term after let, with and without pairs and colons. And all this is a mistake.

Thanks for the patience found here.

EDIT:

I will try to synthesize what I rely on four answers (from now on), all is well:

Trying to mimic this pattern:

s : string = "abc"

I tried to write:

type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)

let condition1 lastRet nextRet i fl : StoppingCondition =  // BAD 
    //wrong for a type alias, totally wrong for a union constructor
    true
    //or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
    true

or other inserts : Stopping Condition(attempting a prefix in how the constructors go on this line).

Now I see that in order to get what I get, I have to do:

type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl =   //...
    true
let stoppingCondition1 = StoppingCondition conditionFunc1 
    //or
let stoppingCondition2 = StoppingCondition <| (func lastRet nextRet i fl -> false) 
    //and there another variation or 2 below

, , - , . of string - " ". , union of string - . " ( ( )). , . DU - . , :

let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
    //"stoppingCondition1 is not a function and cannot be applied"

, . :

type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0  // b = true

, , , .

2:

. . . , :

(: https://fsharpforfunandprofit.com/posts/defining-functions/):

type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
    //or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y

:

let (f2 : Adder) x y = x + y    // bad 
let (f3 x y) : (decimal -> decimal -> decimal) = x + y   // bad 
let (f3 : (decimal -> decimal -> decimal)) x y  = x + y  // bad

: F # ala Haskell?

( , , " " - , ).

+4
4

, StoppingCondition , :

let Condition1 = StoppingCondition (fun _ _ _ _ -> true)`

- :

let Condition1 = StoppingCondition <| fun lastRet nextRet i fl ->
    // Add function code here

, . , ; :

type MyInput =
    { LastReturn : ReturnType
      NextReturn : ReturnType
      MyInt      : int
      MyFloat    : float }

type StopCondition = StopCondition of (MyInput -> bool)

let impossibleCondition = StopCondition (fun _ -> false)

let moreComplicatedCondition = StopCondition <| fun inp ->
    inp.MyInt < int (round inp.MyFloat)

a StopCondition, :

let testStopCondition (StopCondition c) input = c input
+3

" " StoppingCondition. StoppingCondition Condition1 DU:

let stop = StoppingCondition Condition1

, , , , DU, - ; .

, , - , , ; , , , "" "" - - - StoppingCondition :

type StoppingCondition = ReturnType -> ReturnType -> int -> float -> bool

StoppingCondition , , , /, , ReturnType -> ReturnType -> int -> float -> bool.

+4

:

let Condition1 lastRet nextRet i fl :StoppingCondition=
    true

, , true .

, , ,

let Condition1  :StoppingCondition=
    true

, , .

, ​​, :

let Condition1=fun a b c d -> StoppingCondition(fun a b c d -> whatever)

.

, , ,

+3

, , , , StoppingCondition .

:

let stopWhenNextGreaterThanLast = StoppingCondition (fun last next _ _ -> next > last)

let stopWhenLastGreaterThanLast = StoppingCondition (fun last next _ _ -> last> next)

( , )

, , StoppingCondition.

, , :

let shouldStop stoppingCond last next i value = 
    match stoppingCond with
    |StoppingCondition f -> f last next i value

true false , .

That should be all you need to use this approach in practice.


You can extend this approach by doing something like this to cover several potential stopping conditions:

type StoppingCondition =
    | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
    | Or of StoppingCondition * StoppingCondition

And function modification shouldStop

let rec shouldStop stoppingCond last next i value = 
    match stoppingCond with
    |StoppingCondition f -> f last next i value
    |Or (stp1, stp2) -> (shouldStop stp1 last next i value) || (shouldStop stp2 last next i value)

Now, if we have one condition, we stop when it occurs, or if we fulfill several conditions, we can check if any of them is fulfilled.

Then you could Ortogether create new stop conditions from the base condition:

let stopWhenIIsEven = StoppingCondition (fun _ _ i _ -> i % 2 = 0)

let stopWhenValueIsZero = StoppingCondition (fun _ _ _ value -> value = 0.0)

let stopWhenIEvenOrValueZero = Or (stopWhenIIsEven, stopWhenValueIsZero)
+1
source

All Articles