I'm a beginner to F# and playing around with it, until I faced this problem. I searched for it but couldn't find anything. I want to mutate an object into another. I have Geolocation object With lots of properties, two of them the Latitude and Longitude. I want to create a new dynamic object but using a pipe or a select operator, with only that subset of properties
let customLocation = OtherPlace.Geolocation ....
how can I do this?
The best way to solve this sort of problem is to create a discriminated union with a single case. You could use a straight type alias, but you would lose a small amount of type safety. To define the type use:
type Loc = |LL of float * float
and then you can create instances with something like:
Something |> fun t -> LL(t.Latitude,t.Longitude)
or the simpler version:
LL(something.Latitude,something.Longitude)
let's say you have an array of OtherPlace.Geolocation
geoLocations : OtherPlace.Geolocation array
you can then, depending on your need :
use a tuple (which is just a special case of a record)
.
//of type (double * double) array
let g = geoLocations |> Array.map (fun x -> x.Latitude, x.Longitude)
create a record type (nb : a tuple is just a record with positional names)
.
type Position = {Latitude : double; Longitude : double}
//of type Position array
let g = geoLocations |> Array.map (fun x -> x.Latitude, x.Longitude)
For small local need, a tuple is better suited but can become unwieldy.
Records allow you to better structure the program
Union case should be used to differentiate between different things, that still represent some common concept.
For instance you could have the position to be expressed in different system
type GeoPosition = | LaTLong of double * double
| WGS84 of double * double
| ...
//of type GeoPosition array
let g = geoLocations |> Array.map (fun x -> LatLong (x.Latitude, x.Longitude))
PS : if you use F# 3.1 you have one additional sugar for naming union type fields as shown here
Related
In imperative programming, there is concise syntax sugar for changing part of an object, e.g. assigning to a field:
foo.bar = new_value
Or to an element of an array, or in some languages an array-like list:
a[3] = new_value
In functional programming, the idiom is not to mutate part of an existing object, but to create a new object with most of the same values, but a different value for that field or element.
At the semantic level, this brings about significant improvements in ease of understanding and composing code, albeit not without trade-offs.
I am asking here about the trade-offs at the syntax level. In general, creating a new object with most of the same values, but a different value for one field or element, is a much more heavyweight operation in terms of how it looks in your code.
Is there any functional programming language that provides syntax sugar to make that operation look more concise? Obviously you can write a function to do it, but imperative languages provide syntax sugar to make it more concise than calling a procedure; do any functional languages provide syntax sugar to make it more concise than calling a function? I could swear that I have seen syntax sugar for at least the object.field case, in some functional language, though I forget which one it was.
(Performance is out of scope here. In this context, I am talking only about what the code looks like and does, not how fast it does it.)
Haskell records have this functionality. You can define a record to be:
data Person = Person
{ name :: String
, age :: Int
}
And an instance:
johnSmith :: Person
johnSmith = Person
{ name = "John Smith"
, age = 24
}
And create an alternation:
johnDoe :: Person
johnDoe = johnSmith {name = "John Doe"}
-- Result:
-- johnDoe = Person
-- { name = "John Doe"
-- , age = 24
-- }
This syntax, however, is cumbersome when you have to update deeply nested records. We've got a library lens that solves this problem quite well.
However, Haskell lists do not provide an update syntax because updating on lists will have an O(n) cost - they are singly-linked lists.
If you want efficient update on list-like collections, you can use Arrays in the array package, or Vectors in the vector package. They both have the infix operator (//) for updating:
alteredVector = someVector // [(1, "some value")]
-- similar to `someVector[1] = "some value"`
it is not built-in, but I think infix notation is convenient enough!
One language with that kind of sugar is F#. It allows you to write
let myRecord3 = { myRecord2 with Y = 100; Z = 2 }
Scala also has sugar for updating a Map:
ms + (k -> v)
ms updated (k,v)
In a language such as Haskell, you would need to write this yourself. If you can express the update as a key-value pair, you might define
let structure' =
update structure key value
or
update structure (key, value)
which would let you use infix notation such as
structure `update` (key, value)
structure // (key, value)
As a proof of concept, here is one possible (inefficient) implementation, which also fails if your index is out of range:
module UpdateList (updateList, (//)) where
import Data.List (splitAt)
updateList :: [a] -> (Int,a) -> [a]
updateList xs (i,y) = let ( initial, (_:final) ) = splitAt i xs
in initial ++ (y:final)
infixl 6 // -- Same precedence as +
(//) :: [a] -> (Int,a) -> [a]
(//) = updateList
With this definition, ["a","b","c","d"] // (2,"C") returns ["a","b","C","d"]. And [1,2] // (2,3) throws a runtime exception, but I leave that as an exercise for the reader.
H. Rhen gave an example of Haskell record syntax that I did not know about, so I’ve removed the last part of my answer. See theirs instead.
So I have some json response content represented as string and I want to get its property names.
What I am doing
let properties = Newtonsoft.Json.Linq.JObject.Parse(responseContent).Properties()
let propertyNames, (jprop: JProperty) = properties.Select(jprop => jprop.Name);
According to this answer I needed to annotate the call to the extension method, however, I still get the error.
A unique overload for method 'Select' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: (extension) Collections.Generic.IEnumerable.Select<'TSource,'TResult>(selector: Func<'TSource,'TResult>) : Collections.Generic.IEnumerable<'TResult>, (extension) Collections.Generic.IEnumerable.Select<'TSource,'TResult>(selector: Func<'TSource,int,'TResult>) : Collections.Generic.IEnumerable<'TResult>
Am I doing something wrong?
First, the syntax x => y you're trying to use is C# syntax for lambda expressions, not F# syntax. In F#, the correct syntax for lambda-expressions is fun x -> y.
Second, the syntax let a, b = c means "destructure the pair". For example:
let pair = (42, "foo")
let a, b = pair // Here, a = 42 and b = "foo"
You can provide a type annotation for one of the pair elements:
let a, (b: string) = pair
But this won't have any effect on pair the way you apparently expect it to work.
In order to provide type annotation for the argument of a lambda expression, just annotate the argument, what could be simpler?
fun (x: string) -> y
So, putting all of the above together, this is how your line should look:
let propertyNames = properties.Select(fun (jprop: JProperty) -> jprop.Name)
(also, note the absence of semicolon at the end. F# doesn't require semicolons)
If you have this level of difficulty with basic syntax, I suggest you read up on F# and work your way through a few examples before trying to implement something complex.
Currently, I'm trying to teach myself some F# by making an application that consists of a C# GUI layer and an F# business layer. In the GUI layer, the user will at some point have to make a choice by selecting a value that is part of a simple enum, e.g. selecting either of the following:
enum {One, Two, Three}
I have written a function to translate the enum value to an F# discriminated union
type MyValues =
| One
| Two
| Three
Now I have to translate back, and am already tired of the boilerplate code. Is there a generic way to translate my discriminated union to the corresponding enum, and vice versa?
Cheers,
You can also define the enum in F# and avoid doing conversions altogether:
type MyValues =
| One = 0
| Two = 1
| Three = 2
The = <num> bit tells the F# compiler that it should compile the type as a union. When using the type from C#, this will appear as a completely normal enum. The only danger is that someone from C# can call your code with (MyValues)4, which will compile, but it will cause incomplete pattern match exception if you are using match in F#.
Here are generic DU/enum converters.
open Microsoft.FSharp.Reflection
type Union<'U>() =
static member val Cases =
FSharpType.GetUnionCases(typeof<'U>)
|> Array.sortBy (fun case -> case.Tag)
|> Array.map (fun case -> FSharpValue.MakeUnion(case, [||]) :?> 'U)
let ofEnum e =
let i = LanguagePrimitives.EnumToValue e
Union.Cases.[i - 1]
let toEnum u =
let i = Union.Cases |> Array.findIndex ((=) u)
LanguagePrimitives.EnumOfValue (i + 1)
let du : MyValues = ofEnum ConsoleColor.DarkGreen
let enum : ConsoleColor = toEnum Three
It maps the DU tag to the enum underlying value.
I'm trying to make a function that defines a vector that varies based on the function's input, and set! works great for this in Scheme. Is there a functional equivalent for this in OCaml?
I agree with sepp2k that you should expand your question, and give more detailed examples.
Maybe what you need are references.
As a rough approximation, you can see them as variables to which you can assign:
let a = ref 5;;
!a;; (* This evaluates to 5 *)
a := 42;;
!a;; (* This evaluates to 42 *)
Here is a more detailed explanation from http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-core.html:
The language we have described so far is purely functional. That is, several evaluations of the same expression will always produce the same answer. This prevents, for instance, the implementation of a counter whose interface is a single function next : unit -> int that increments the counter and returns its new value. Repeated invocation of this function should return a sequence of consecutive integers — a different answer each time.
Indeed, the counter needs to memorize its state in some particular location, with read/write accesses, but before all, some information must be shared between two calls to next. The solution is to use mutable storage and interact with the store by so-called side effects.
In OCaml, the counter could be defined as follows:
let new_count =
let r = ref 0 in
let next () = r := !r+1; !r in
next;;
Another, maybe more concrete, example of mutable storage is a bank account. In OCaml, record fields can be declared mutable, so that new values can be assigned to them later. Hence, a bank account could be a two-field record, its number, and its balance, where the balance is mutable.
type account = { number : int; mutable balance : float }
let retrieve account requested =
let s = min account.balance requested in
account.balance <- account.balance -. s; s;;
In fact, in OCaml, references are not primitive: they are special cases of mutable records. For instance, one could define:
type 'a ref = { mutable content : 'a }
let ref x = { content = x }
let deref r = r.content
let assign r x = r.content <- x; x
set! in Scheme assigns to a variable. You cannot assign to a variable in OCaml, at all. (So "variables" are not really "variable".) So there is no equivalent.
But OCaml is not a pure functional language. It has mutable data structures. The following things can be assigned to:
Array elements
String elements
Mutable fields of records
Mutable fields of objects
In these situations, the <- syntax is used for assignment.
The ref type mentioned by #jrouquie is a simple, built-in mutable record type that acts as a mutable container of one thing. OCaml also provides ! and := operators for working with refs.
Im a student who is really new to functional programming. Im working on a banking application where the data has been already defined as,
type Accountno = Int
data Accounttype = Saving | Current | FixedDeposit deriving (Show,Read)
type Accountamount = Int
type Name = String
type Account = (Accountno, Name, Accounttype, Accountamount)
exampleBase :: [Account]
exampleBase = [ (1,"Jennifer",Saving,1000 ) ,
(5,"Melissa",Current,3000) ,
(2,"Alex",Saving,1500)]
Im trying to sort the list by its account number using the following code,
sortByID :: (Ord a) => [a] -> [a]
sortByID [] = []
sortByID (l :ls) =
let
smallerSorted = sortByID [x | x <- ls, x <= l]
biggerSorted = sortByID [x | x <- ls, x > l]
in
smallerSorted ++ [l] ++ biggerSorted
viewSortedDetails :: IO()
viewSortedDetails =
do
putStrLn "Account Details Sorted By Account ID"
let records = sortByID exampleBase
let viewRecord = map show records
mapM_ putStrLn viewRecord
But I do not get the expected result. as it gives me an error, informing "Instance of Ord Accounttype required for definition of viewSortedDetails".Please can some one help me to overcome this problem
Thanks a lot!
Well, the problem is that you're using ordering comparisons, such as <=, on two Account values, which would require Account to be an instance of Ord. Now, Account is a synonym for a four-element tuple, which are defined to be instances of Ord when all the types in the tuple are. Accountno, Name, and Accountamount are all synonyms for types with Ord instances, but Accounttype is not.
You could make it possible to sort Account values directly by making Accounttype an instance of Ord, which you can do by simply adding it to the deriving clause.
However, if you want to specifically sort only by the account number, not the other elements of the tuple, you'll need to do something differently. One option would be to make Account a data type with a custom Ord instance:
data Account = Account Accountno Name Accounttype Accountamount deriving (Eq, Show, Read)
instance Ord Account where
(...)
Then you can define the ordering however you like.
Alternatively, you can leave it as is and instead only compare the element you want instead of the entire Account value, using something like this:
accountNo :: Account -> Accountno
accountNo (n,_,_,_) = n
...and then doing the comparison with something like smallerSorted = sortByID [x | x <- ls, accountNo x <= accountNo l]. The standard libraries also include a function on for this purpose, but it would awkward to use in this case.
A few other remarks, which are less relevant to your question, on the general subject of Haskell code:
Defining Account as a data type, probably using the record syntax, would be nicer than using a type synonym here. Large tuples can be awkward to work with.
Accountno and Accountamount should probably be different types as well, to avoid mixing them with other Ints: the first because doing arithmetic on account numbers makes little sense, the latter in part because (I'm guessing) you're implicitly using fixed point arithmetic, such that 100 actually means 1.00, and in general just to avoid confusion.
In fact, Int is probably a bad choice for Accountamount anyway: Why not something from Data.Fixed, Ratio Integer, or a base-10-safe floating point type (although there isn't one in the standard libraries, unfortunately).
The standard libraries of course include sorting functions already--I'm assuming the reimplementation is for learning purposes, but in practice it could all be replaced by something like sortBy (compare `on` accountNo).