AMcNall
AMcNall

Reputation: 529

Adding to a type in fsharp

I am having some difficulty in a task in fsharp.

At the moment I have a useful type pre-declared e.g.

type TESTA =
{ foo : Float
  bar: factorA.double
}

Due to the nature of the type (used elsewhere) I cannot change it directly (or re declare it in the same way). However I need to add another definition to the set, just a simple bool, so the type could look like this (if I could change it direct)

type TESTA =
{ foo : Float
  bar: factorA.double
  truth: bool
}

How can I get the same effect without changing the type directly? I have tried:

type Final=
{ PartA: TESTA
  truth: bool
}

But creating this sort of 'subtype' doesnt allow me to access foo/bar separately (as far as I can test):

let unittest =
  {  Final.TESTA.foo = X <- this doesnt work :(
    Final.truth = true <- this does work
  }

Thanks

Upvotes: 3

Views: 122

Answers (2)

asibahi
asibahi

Reputation: 887

None of the examples you provided are working code, but that aside: to expand on what Ringil added, this is the proper way to use Records:

type TESTA =
    { foo : float
      bar : int
      }

type Final = 
    { PartA : TESTA
      Truth : bool 
      }

let TestaTest = 
    { TESTA.foo = 1.0
      TESTA.bar = 0
      }

let FinalTest = 
    { Final.PartA = TestaTest
      Final.Truth = true
      }

let FinalTest2 = { FinalTest with PartA = { FinalTest.PartA with foo = 2.0 } }

let TestaMember = FinalTest2.PartA 

This is all working code.

If you're only using this new type in specific places, would it make more sense to use a tuple instead ?

let ConvenientTuple = (TestaTest, true)

// Then to use it with pattern matching, for example:
match ConvenientTuple with 
| _, false -> DoSomething()
| n, true when n.foo > 1.0 -> DoAnotherThing(n)
| m, true -> DoDefaultThing(n)

check out F# for fun and profit page on records

Upvotes: 4

Ringil
Ringil

Reputation: 6537

Your Final type should work, you just need to create the TESTA type manually. So you can do something like this:

let unittest =
  {  Final.PartA = {foo = X; bar = Y};
     Final.truth = true
  }

If you have a lot of nested record types like this, you might want to consider trying out Aether and its Lenses feature.

Upvotes: 8

Related Questions