Warm tip: This article is reproduced from stackoverflow.com, please click
f#

How to access elements correctly in own defined type in F#

发布于 2020-04-19 09:29:50

I'm just starting to learn F# and am confused with this school assignment. Please excuse me if this is a dumb question, I couldn't find the answer by searching. The assignment wants me to:

The set of complex numbers is the set of pairs of real numbers.

Define a type complex that represents complex numbers with floating point components.

Define a function mkComplex : float -> float -> complex that given two floating point numbers return the corresponding complex number.

Define a function complexToPair : complex -> float * float that given a complex number (a,b) returns the pair (a, b) .

Here's my attempt at this: first I define the type complex:

type Complex = float * float

I define the function mkComplex:

let mkComplex a b = Complex (a, b)

The function complexToPair is the one giving me trouble. How do I given the complex type access the elements inside it correctly? the following works runs fine but I am getting spammed with typecheck errors.

let complexToPair (a: Complex) = (a.[0], a.[1])

a.[0] and a.[1] is underlined in red and giving me the following warning:

The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints.

So, what am I doing wrong? The code works just fine.

Questioner
PineappleDude
Viewed
67
Tomas Petricek 2020-02-05 05:52

The type definition that you are using is defining a type alias. When you say:

type Complex = float * float

Then the type Complex is just a tuple. You can create its values using (1.0, 1.0). When you have a value c of this type, you can access elements using fst c and snd c, or by using pattern matching.

Using a type alias is sometimes useful, but I guess that, in this case, it would be more desirable to use a single-case discriminated union or a record, i.e.:

type Complex = { a:float; b:float }       // Using a record
type Complex = Complex of float * float   // Using a discriminated union

The documentation on F# records explains everything you need to know about using records. For single-case discriminated unions, you can refer to an article in the Desinging with Types series at F# for Fun and Profit.