F# frontend coverage
The F# frontend compiles a subset of F#. Before it lowers a document, admission checks the syntax and refuses each construct outside the subset with an error diagnostic. All refusals of a run are reported together, and the frontend writes no model. The overview describes the supported subset.
This page is generated from the admission catalog of the frontend, so it lists every code that admission can report. Each rule has a minimal example that gives only its own code. The conformance corpus has one refusal case for each code. Codes are stable once released.
Codes
The fallback rules below refuse any expression, pattern, type or declaration outside the supported subset that no specific rule refused.
| Code | Construct |
|---|---|
fsharp.unsupported_expression | expression outside the supported subset |
fsharp.unsupported_pattern | pattern outside the supported subset |
fsharp.unsupported_type | type outside the supported subset |
fsharp.unsupported_declaration | declaration outside the supported subset |
Rules
fsharp.unsupported_mutable
Construct: mutable binding or field
Message: Mutable bindings and fields are not supported; Morphir values are immutable.
Suggestion: Use a new let binding, or a record update, instead of changing a value.
Example. The diagnostic is at mutable.
Example.fs:
namespace Acme.Demo
module Example =
let mutable total = 0
fsharp.unsupported_assignment
Construct: assignment
Message: Assignment with ‘<-’ is not supported; Morphir values are immutable.
Suggestion: Return a new value instead of changing an existing one.
Example. The diagnostic is at builder.Length <- 0.
Example.fs:
namespace Acme.Demo
module Example =
let reset (builder: System.Text.StringBuilder) = builder.Length <- 0
fsharp.unsupported_loop
Construct: loop
Message: Loops (‘for’, ‘while’) are not supported; Morphir has no statements.
Suggestion: Use recursion or a List function such as List.map or List.fold.
Example. The diagnostic is at for index in 1 .. 3 do ignore index.
Example.fs:
namespace Acme.Demo
module Example =
let count () = for index in 1 .. 3 do ignore index
fsharp.unsupported_class
Construct: class
Message: Classes are not supported; Morphir types are records, unions and type abbreviations.
Suggestion: Use a record for the data and module functions for the behavior.
Example. The diagnostic is at this text:
Counter() =
member _.Value = 1
Example.fs:
namespace Acme.Demo
module Example =
type Counter() =
member _.Value = 1
fsharp.unsupported_interface
Construct: interface
Message: Interfaces are not supported; Morphir has no subtyping.
Suggestion: Use a record of functions, or a union of the cases.
Example. The diagnostic is at this text:
IShape =
abstract Area: float
Example.fs:
namespace Acme.Demo
module Example =
type IShape =
abstract Area: float
fsharp.unsupported_member
Construct: member
Message: Members and type extensions are not supported; Morphir types have no methods.
Suggestion: Define a module function that takes the value as a parameter.
Example. The diagnostic is at member this.Double = this.Seats * 2.
Example.fs:
namespace Acme.Demo
module Example =
type Car = { Seats: int } with
member this.Double = this.Seats * 2
fsharp.unsupported_object_expression
Construct: object expression
Message: Object expressions are not supported; Morphir has no objects.
Suggestion: Use a record of functions.
Example. The diagnostic is at { new System.Object() with member _.ToString() = "x" }.
Example.fs:
namespace Acme.Demo
module Example =
let text = { new System.Object() with member _.ToString() = "x" }
fsharp.unsupported_sequence_expression
Construct: sequence expression
Message: Sequence expressions (‘seq { }’) are not supported; Morphir has no lazy sequences.
Suggestion: Use a list and the List functions.
Example. The diagnostic is at { yield 1 }.
Example.fs:
namespace Acme.Demo
module Example =
let numbers = seq { yield 1 }
fsharp.unsupported_computation_expression
Construct: computation expression
Message: Computation expressions are not supported; Morphir has no effects or builders.
Suggestion: Write the steps as plain functions, for example with Result.bind.
Example. The diagnostic is at { return 1 }.
Example.fs:
namespace Acme.Demo
module Example =
let work = async { return 1 }
fsharp.unsupported_comprehension
Construct: list comprehension or range
Message: List comprehensions and ranges (’[ for … ]’, ‘[ 1 .. 3 ]’) are not supported.
Suggestion: Use List.map, List.filter or an explicit list.
Example. The diagnostic is at [ for x in [ 1; 2 ] -> x * x ].
Example.fs:
namespace Acme.Demo
module Example =
let squares = [ for x in [ 1; 2 ] -> x * x ]
fsharp.unsupported_array
Construct: array
Message: Arrays are not supported; Morphir collections are immutable lists.
Suggestion: Use a list.
Example. The diagnostic is at [| 1; 2 |].
Example.fs:
namespace Acme.Demo
module Example =
let numbers = [| 1; 2 |]
fsharp.unsupported_exception
Construct: exception
Message: Exceptions (’exception’, ’try … with’, ’try … finally’) are not supported; Morphir has no effects.
Suggestion: Return a Result or an option.
Example. The diagnostic is at exception Failed of string.
Example.fs:
namespace Acme.Demo
module Example =
exception Failed of string
fsharp.unsupported_active_pattern
Construct: active pattern
Message: Active patterns are not supported; Morphir patterns match only constructors and values.
Suggestion: Use a union and a function that returns it.
Example. The diagnostic is at let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd.
Example.fs:
namespace Acme.Demo
module Example =
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd
fsharp.unsupported_unit_of_measure
Construct: unit of measure
Message: Units of measure are not supported; Morphir numbers carry no unit.
Suggestion: Use a single-case union to name the quantity.
Example. The diagnostic is at [<Measure>] type kg.
Example.fs:
namespace Acme.Demo
module Example =
[<Measure>] type kg
fsharp.unsupported_quotation
Construct: quotation
Message: Quotations are not supported; Morphir models values, not code.
Example. The diagnostic is at <@ 1 + 1 @>.
Example.fs:
namespace Acme.Demo
module Example =
let expression = <@ 1 + 1 @>
fsharp.unsupported_anonymous_record
Construct: anonymous record
Message: Anonymous records are not supported; Morphir record types have names.
Suggestion: Declare a record type.
Example. The diagnostic is at {| X = 1 |}.
Example.fs:
namespace Acme.Demo
module Example =
let point = {| X = 1 |}
fsharp.unsupported_struct
Construct: struct type or struct tuple
Message: Struct types and struct tuples are not supported; Morphir has no value-type layout.
Suggestion: Remove [
Example. The diagnostic is at struct (1, 2).
Example.fs:
namespace Acme.Demo
module Example =
let pair = struct (1, 2)
fsharp.unsupported_inline
Construct: inline function
Message: Inline functions are not supported; Morphir functions are not specialized at their call sites.
Suggestion: Remove ‘inline’ and give the parameters concrete types.
Example. The diagnostic is at inline.
Example.fs:
namespace Acme.Demo
module Example =
let inline double (x: int) = x * 2
fsharp.unsupported_attribute
Construct: attribute with an effect
Message: This attribute changes the meaning of the code and is not supported.
Suggestion: Remove the attribute. Only RequireQualifiedAccess, AutoOpen, CompilationRepresentation, CompiledName and MorphirName are accepted.
Example. The diagnostic is at Literal.
Example.fs:
namespace Acme.Demo
module Example =
[<Literal>]
let Limit = 10
fsharp.unsupported_type_test
Construct: type test
Message: Type tests (’:?’) are not supported; Morphir has no runtime types.
Suggestion: Use a union to tell the cases apart.
Example. The diagnostic is at value :? string.
Example.fs:
namespace Acme.Demo
module Example =
let isText (value: obj) = value :? string
fsharp.unsupported_cast
Construct: cast
Message: Casts (’:>’, ‘:?>’, ‘upcast’, ‘downcast’) are not supported; Morphir has no subtyping.
Example. The diagnostic is at 1 :> obj.
Example.fs:
namespace Acme.Demo
module Example =
let boxed = (1 :> obj)
fsharp.unsupported_null
Construct: null
Message: ’null’ is not supported; Morphir values are never null.
Suggestion: Use an option.
Example. The diagnostic is at null.
Example.fs:
namespace Acme.Demo
module Example =
let nothing: string = null
fsharp.unsupported_use
Construct: use binding
Message: ‘use’ bindings are not supported; Morphir has no resources to dispose.
Suggestion: Use ’let’.
Example. The diagnostic is at this text:
use stream = new System.IO.MemoryStream()
stream.Length
Example.fs:
namespace Acme.Demo
module Example =
let size () =
use stream = new System.IO.MemoryStream()
stream.Length
fsharp.unsupported_sequential
Construct: sequential expression
Message: Sequential expressions (‘a; b’) are not supported; Morphir values have no side effects.
Suggestion: Remove the expression whose value is discarded.
Example. The diagnostic is at this text:
ignore 1
2
Example.fs:
namespace Acme.Demo
module Example =
let both () =
ignore 1
2
fsharp.unsupported_literal
Construct: literal of an unsupported type
Message: This literal type is not supported; Morphir numbers are Int, Float and Decimal.
Suggestion: Use an int, int64, float or decimal literal.
Example. The diagnostic is at 1uy.
Example.fs:
namespace Acme.Demo
module Example =
let small = 1uy
fsharp.unsupported_enum
Construct: enum
Message: Enums are not supported; Morphir custom types have no numeric values.
Suggestion: Use a union without fields.
Example. The diagnostic is at this text:
Color =
| Red = 0
| Blue = 1
Example.fs:
namespace Acme.Demo
module Example =
type Color =
| Red = 0
| Blue = 1
fsharp.unsupported_delegate
Construct: delegate
Message: Delegates are not supported; Morphir has function types.
Suggestion: Use a function type.
Example. The diagnostic is at Handler = delegate of int -> unit.
Example.fs:
namespace Acme.Demo
module Example =
type Handler = delegate of int -> unit
fsharp.unsupported_pattern_guard
Construct: pattern guard
Message: Pattern guards (‘when’) are not supported; a Morphir pattern has no condition.
Suggestion: Match the case, then use ‘if’ in its body.
Example. The diagnostic is at n > 3.
Example.fs:
namespace Acme.Demo
module Example =
let size n =
match n with
| n when n > 3 -> "big"
| _ -> "small"
fsharp.unsupported_or_pattern
Construct: or pattern
Message: Or patterns (‘A | B’) are not supported; a Morphir case has one pattern.
Suggestion: Write one case for each alternative.
Example. The diagnostic is at 1 | 2.
Example.fs:
namespace Acme.Demo
module Example =
let low n =
match n with
| 1 | 2 -> true
| _ -> false
fsharp.unsupported_record_pattern
Construct: record pattern
Message: Record patterns are not supported.
Suggestion: Bind the record to a variable and read its fields.
Example. The diagnostic is at { Seats = s }.
Example.fs:
namespace Acme.Demo
module Example =
type Car = { Seats: int }
let seats car =
match car with
| { Seats = s } -> s
fsharp.unsupported_list_pattern
Construct: list pattern with elements
Message: List patterns with elements (’[ a; b ]’) are not supported.
Suggestion: Use ‘::’ and ‘[]’ patterns.
Example. The diagnostic is at [ a ].
Example.fs:
namespace Acme.Demo
module Example =
let first xs =
match xs with
| [ a ] -> a
| _ -> 0
fsharp.unsupported_named_field_pattern
Construct: named field pattern
Message: Named field patterns (‘Case(field = p)’) are not supported.
Suggestion: Match the fields by position.
Example. The diagnostic is at Rented(days = d).
Example.fs:
namespace Acme.Demo
module Example =
type Status = Rented of days: int
let days status =
match status with
| Rented(days = d) -> d
fsharp.unsupported_conditional_compilation
Construct: conditional compilation
Message: Conditional compilation (’#if’) is not supported, because this frontend does not choose defines.
Suggestion: Remove the directive, or keep one branch.
Example. The diagnostic is at #if DEBUG.
Example.fs:
namespace Acme.Demo
module Example =
#if DEBUG
let mode = "debug"
#else
let mode = "release"
#endif
fsharp.unsupported_signature_file
Construct: signature file
Message: Signature files (’.fsi’) are not supported; access comes from F# visibility and the exposed modules.
Suggestion: Remove the signature file and use ‘private’ or ‘internal’.
Example. The diagnostic is an empty range at the start of the first document.
Example.fsi:
namespace Acme.Demo
module Example =
val total: int
Example.fs:
namespace Acme.Demo
module Example =
let total = 1
fsharp.unsupported_expression
Construct: expression outside the supported subset
Message: This kind of expression is not supported by the F# frontend.
Example. The diagnostic is at lazy 1.
Example.fs:
namespace Acme.Demo
module Example =
let later = lazy 1
fsharp.unsupported_pattern
Construct: pattern outside the supported subset
Message: This kind of pattern is not supported by the F# frontend.
Example. The diagnostic is at (a, _) & (_, b).
Example.fs:
namespace Acme.Demo
module Example =
let both pair =
match pair with
| (a, _) & (_, b) -> a + b
fsharp.unsupported_type
Construct: type outside the supported subset
Message: This kind of type is not supported by the F# frontend.
Example. The diagnostic is at #seq<int>.
Example.fs:
namespace Acme.Demo
module Example =
let total (values: #seq<int>) = Seq.sum values
fsharp.unsupported_declaration
Construct: declaration outside the supported subset
Message: This kind of declaration is not supported by the F# frontend.
Example. The diagnostic is at do ignore 1.
Example.fs:
namespace Acme.Demo
module Example =
do ignore 1
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.