Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error for Kleisli composition

Tags:

f#

I have a validation module copied from Railway oriented programming that performs error handling in my application:

type ErrorMessage = ErrorMessage of string

type ValidationResult<'T> =
    | Success of 'T
    | Error of ErrorMessage

module ValidationResult =    
    let doubleMap successHandler errorHandler = function
        | Success x -> successHandler x
        | Error e -> errorHandler e

    let bind f = function
        | Success x -> f x
        | Error e -> Error e

    let (>=>) f g = f >> bind g

I was testing the Kleisli composition by using the following test functions:

let validation1 (list: int list) =
    if List.length list = 6
    then Success list
    else Error <| ErrorMessage "Length error"

let validation2 list =
    if List.forall (fun x -> x > 6) list
    then Success list
    else Error <| ErrorMessage "All elements must be larger than 6"

let combined = validation1 >=> validation2
                              //^^^^^^^^^^^^ compile error

To my understanding, validation1 and validation2 should compose because both are of type int list -> ValidationResult<int list>. However I got a compile error

Expecting a type supporting the operator '>=>' but given a function type. You may be missing an argument to a function.

How can I solve this?

like image 873
rexcfnghk Avatar asked Apr 09 '26 03:04

rexcfnghk


1 Answers

It seems that you simply forgot to open ValidationResult, so your composition operator is not in scope.

For a normal function, F# would have complained that the symbol was undefined. But operators are a different matter.

Operators can be defined in two ways: as a standalone function (the functional way) or as a static member on one of the types passed to the operator (the .NET way). In the former case, the function needs to be visible in scope, but in the latter case it doesn't: as long as you managed to get hold of an object with an operator defined as static member, you don't need to have its type visible.

This is why F# says that it "expected a type supporting operator" instead of "function is undefined".

like image 114
Fyodor Soikin Avatar answered Apr 12 '26 14:04

Fyodor Soikin