Is it possible to set the DataLoadOptions on a data context in F#? So far I have had no luck because the DataLoadOptions.LoadWith() takes a System.Linq.Expressions.LambdaExpression which seems impossible to instantiate in F#
I believe this should be possible. You'll need to reference FSharp.PowerPack.Linq.dll which adds support for translating F# quotations (written using <# fun x -> x.Foo #>) to C# expression trees. Something like this should do the trick:
#r #"FSharp.PowerPack.Linq.dll"
open System
open System.Linq.Expressions
open Microsoft.FSharp.Linq.QuotationEvaluation
let e = <# Func<int, int>(fun x -> 1 + x) #>
let lambda = e.ToLinqExpression() :?> LambdaExpression
Note that the quotation creates a Func<...> delegate, which is translated to expression tree that can be converted to LambdaExpression (normal F# functions are represented differently).
Related
I see those two main advantages to postfix over prefix notations for unary functions:
nice formatting, no nesting
maps better the Input -> Function -> Ouput way of thinking about data processing.
Here is an example:
def plus2(v: Int) = v + 2
def double(v: Int) = v * 2
def square(v: Int) = v * v
// prefix
square(
double(
plus2(1)
)
)
// postfix
1.plus2
.double
.square
This can be emulated as in the Java stream api with method chaining or other user techniques. But I'm not familiar with any programming language that offers first-class support for postfix function application.
What are the programming language design reasons not to offer first-class postfix notation support for unary functions? It seems trivial to support.
I'm not familiar with any programming language that allows this.
Your example syntax is very similar to method chaining. In object-oriented languages, a method with no arguments is effectively a unary operator on whatever type the method is declared on. So here's your computation in Java, with the same declarations, in postfix order:
class Example {
final int x;
Example(int x) { this.x = x; }
Example add2() { return new Example(x + 2); }
Example mult2() { return new Example(x * 2); }
Example square() { return new Example(x * x); }
public static void main(String[] args) {
Example result =
new Example(1)
.add2()
.mult2()
.square();
}
}
You need the brackets () to call them, of course, but it's still postfix order. Unfortunately, you can't adapt this to use static methods instead of instance methods, at least not without abusing Optional or Stream like this:
Optional.of(1)
.map(StaticExample::add2)
.map(StaticExample::mult2)
.map(StaticExample::square)
.get()
I guess the reason OOP languages don't make it easier to use static methods this way is because it would be strange to have special syntax which privileges static methods over instance methods. The point of OOP is to do things with instances and polymorphism.
It's also possible in functional languages, using functions instead of methods: here's F#:
let add2 x = x * 2
let double x = x * 2
let square x = x * x
let result =
1
|> add2
|> double
|> square
Here the forward pipe operator |> serves a different semantic role to the . in Java, but the effect is the same: the functions are written in postfix order.
I guess the main reason that the forward pipe operator only tends to exist in functional languages is because partial application allows you to write a pipeline-style computation using non-unary functions. For example:
nums
|> List.filter isEven
|> List.map square
Here, List.filter and List.map take two arguments, but if you call them with one argument then they return a unary function. Non-functional languages tend not to have partial application (at least not so easily), so a forward pipe operator would be less useful.
There is also the less-well-known concatenative programming paradigm, where everything is naturally done in postfix order, with no extra syntax required. Here's my own toy language named fffff:
(2 +) >!add2
(2 *) >!double
(# *) >!square
1 add2 double square >result
Here, even the assignments like >result are done in postfix order.
In Aeson library meant for object serializing/deserializing, I see the functions, FromJSON & ToJSON declared as instances. The code is,
data Coord = Coord { x :: Double, y :: Double }
deriving (Show)
instance ToJSON Coord where
toJSON (Coord xV yV) = object [ "x" .= xV,
"y" .= yV ]
My questions are,
Why does the author create ToJSON/FromJSON instances with just one method? Can't toJSON/parseJSON be written as a function on its own?
In Python, one just does json.loads/json.dumps to handle any kind of object/json-string. Why does the haskell user need to write all these extra code for every object that he seralizes?
For composite objects with multiple hierarchies like
{"a":
{"b":
{
"c":1
}
}
}
, do we need to create multiple data and instance at each level?
Why does the author create ToJSON/FromJSON instances with just one method? Can't toJSON/parseJSON be written as a function on its own?
You misunderstand a lot of things, so let me clear this up a little. ToJSON and FromJSON aren't functions. These are typeclasses. Typeclasses are a way to write polymorphic code in Haskell.
Here I would explain a very simplified and incomplete definition of json serialization. First of all we declare a typeclass:
class ToJSON a where
toJSON :: a -> String
This statement basically says: "If a is an instance of typeclass ToJSON, then we can use function toJSON to serialize a into a JSON string".
When a typeclass is defined, one can implement instances of it for a variety of simple types:
instance ToJSON String where
toJSON s = s
instance ToJSON Int where
toJSON n = show n
instance ToJSON Double where
toJSON n = show n
After you defined these simple implementation, you can apply toJSON to values of either String, Int or Double and it would get dispatched to a right implementation:
toJSON "hello" -----> "hello"
toJSON (5 :: Int) -----> "5"
toJSON (5.5 :: Double) -----> "5.5"
To go further we need a way to encode JSON collections. Let's start with lists. We want to express that if there is a value a that can be serialized into JSON, then a list of such values can also be serialized into JSON.
-- ,-- value 'a' can be serialized into JSON
-- ,--------,
instance (ToJSON a) => ToJSON [a] where
-- ``````````-- A list of such values can also be serialized
-- | Here is how serialization can be performed
toJSON as = "[" ++ (intercalate ", " $ map toJSON as) ++ "]"
We serialize each value in the list, separate them with ", " and enclose in brackets. Note that recursive call to toJSON gets dispatched to the correct implementation.
Now we can use toJSON on lists:
toJSON [1,2,3,4] -----> "[1, 2, 3, 4]"
You can go further and try to implement the whole JSON syntax. Your next step here might be maps. I'll leave it as an exercise.
My point was to explain that when you write instance ToJSON Coord ... you simply provide a way to serialize Coord into JSON. And this gives you an ability to serialize lists of Coords, maps with Coords and many other things. This wouldn't be possible without typeclasses.
In Python, one just does json.loads/json.dumps to handle any kind of object/json-string. Why does the haskell user need to write all these extra code for every object that he seralizes?
An important point is that Python's json.loads wouldn't deserialize json into your object. It would deserialize it into a built in structure that might be equivalent to your object. You can do the same thing in Haskell by using template haskell which would declare ToJSON/FromJSON instances for you. Alternatively you can just dump the JSON into a key value Map and operate on it.
However, writing that extra code (or automatically generating it) gives you a lot of benefits which can be summarized with words "type safety".
For composite objects with multiple hierarchies like ..., do we need to create multiple data and instance at each level?
No you don't. In case of a structure that you linked the instances that would transform a number into such a structure or vice-versa would look approximately like this:
-- | Just a wrapper for the number which must be stored in a nested structure
newtype NestedStructure = NestedStructure Int
instance ToJSON NestedStructure where
toJSON (NestedStructure n) =
object ["a" .= object ["b" .= object ["c" .= n]]]
instance FromJSON NestedStructure where
fromJSON (Object o) = NestedStructure <$> ((o .: "a") >>= (.: "b")
>>= (.: "c"))
fromJSON _ = mzero
In Python, one just does json.loads/json.dumps to handle any kind of
object/json-string. Why does the haskell user need to write all these
extra code for every object that he seralizes?
One way to avoid this is to use the deriving mechanism in combination with GHC.Generics.
The "deriving" mechanism automatically generates typeclass instances for you, avoiding boilerplate. For example:
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
data VDPServer = VDPServer
{ vdpHost :: String
, vdpPort :: Int
, vdpLogin :: String
, vdpPassword :: String
, vdpDatabase :: String
}
deriving Generic
instance FromJSON VDPServer
instance ToJSON VDPServer
This is descrived in the Type Conversion section of the documentation.
You can customize how the instances are generated using the Options type:
aesonOptions :: Options
aesonOptions = defaultOptions
{ sumEncoding = ObjectWithSingleField
, fieldLabelModifier = tail
, omitNothingFields = True
}
instance FromJSON VDPServer where
parseJSON = genericParseJSON aesonOptions
instance ToJSON VDPServer where
toJSON = genericToJSON aesonOptions
Sometimes, when dealing with complex preexisting JSON schemas, this approach doesn't work so well and one has to fall back to manually defining the parser. But for simpler cases it avoids you a lot of boilerplate.
do we need to create multiple data and instance at each level?
All of the record fields must have their own FromJSON/ToJSON instances. Many common types (tuples, lists, maps, strings...) already have such instances, see the instance list for FromJSON in the documentation. But if not, you'll have to define them (maybe using the Generic trick again).
In Python, one just does json.loads/json.dumps to handle any kind of
object/json-string. Why does the haskell user need to write all these
extra code for every object that he seralizes?
The Haskell equivalent of deserializing a JSON file into a composite of maps, lists, and privitive types is to read a Value object. This way one doesn't have to define a new record.
Given the following:
open System.Linq
let seqA = { 1..10 }
this works:
seqA.All (fun n -> n > 0)
However this doesn't:
let abc = fun n -> n > 0
seqA.All (abc)
Why does F# offer implicit conversion from lambda expressions to Funcs but not from functions? Pointers to the documentation where I can read up on what's going on here are welcome. :-)
This is covered in the (rather involved) section of the spec on Method Resolution and again in Type-directed Conversions at Member Invocations. Quoting from the latter:
As described in Method Application Resolution (see §14.4), two
type-directed conversions are applied at method invocations.
The first type-directed conversion converts anonymous function
expressions and other function-valued arguments to delegate types.
Given:
A formal parameter of delegate type D
An actual argument farg of known type ty1 -> ... -> tyn -> rty
Precisely n arguments to the Invoke method of delegate type D
Then:
The parameter is interpreted as if it were written:
new D(fun arg1 ... argn -> farg arg1 ... argn)
It seems to suggest this conversion would be applied to any function value, but observation suggests it's applied only to anonymous functions.
I'm trying to make the following code work (well, compiling first!):
module Orexio.Radix where
import Data.Data
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Typeable
import Text.JSON.Generic
class Resource a where
type Representation a :: *
identifier :: Resource a => Identifier a
class Endpoint a where
call :: Resource a => a -> Representation a
data Identifier a = Identifier [String] deriving (Show)
data Binding a = Binding (JSValue -> Either String JSValue)
bind :: (Data a, Resource a, Endpoint a, Data (Representation a)) => Binding a
bind = Binding (\x -> binding $ query x)
where binding query = fmap (\x -> toJSON $ call x) (resultToEither query)
query jsvalue = fromJSON jsvalue
{-- DEMO --}
data HelloWorld = HelloWorld {
name :: String
} deriving (Show, Typeable, Data)
instance Resource HelloWorld where
type Representation HelloWorld = String
identifier = Identifier ["helloworld"]
instance Endpoint HelloWorld where
call r = "Hello " ++ name r
So I had to enable FlexibleContexts to be able to do Data (Representation a), but still it's not working...
I have this error:
src/Orexio/Radix.hs:21:33:
Could not deduce (Data a0) arising from a use of `query'
from the context (Data a,
Resource a,
Endpoint a,
Data (Representation a))
bound by the type signature for
bind :: (Data a, Resource a, Endpoint a,
Data (Representation a)) =>
Binding a
at src/Orexio/Radix.hs:20:9-78
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Data HelloWorld -- Defined at src/Orexio/Radix.hs:29:29
instance Data () -- Defined in `Data.Data'
instance (Data a, Data b) => Data (a, b) -- Defined in `Data.Data'
...plus 42 others
In the second argument of `($)', namely `query x'
In the expression: binding $ query x
In the first argument of `Binding', namely
`(\ x -> binding $ query x)'
Honestly I'm kinda of lost here, I must be missing something but what?
Here is the other extensions I have activated: DeriveDataTypeable, ExistentialQuantification, NoMonomorphismRestriction, TypeFamilies
Thanks in advance!
It looks like Binding a is supposed to be a function that transforms a value of type a to a value of type Representation a or an error message. Since the input and output are JSON-encoded, however, they both have type JSValue; their types don't mention a at all!
data Binding a = Binding (JSValue -> Either String JSValue)
There's no information to indicate what type those JSValues represent.
In the definition of bind, the compiler knows that the return type is Binding a, but there's no link between that type and the types of JSValues. In particular, the compiler cannot deduce that fromJSON should return an a and that toJSON should take a Representation a. To fix it, add explicit type signatures to binding and query.
One detail that sometimes confuses people is how to tell GHC about type variable scopes. This needs the ScopedTypeVariables extension. Add forall a. to the type signature of bind, and add forall. to the other type signatures in the body of bind so that the variable a is properly scoped.
The essence of the type error is this line: "The type variable `a0' is ambiguous".
(Disclaimer: I'm trying to avoid jargon in this answer.)
To understand what's going on here, I suggest floating the binding and query bindings to the top-level. They successfully typecheck if you then comment out the bind binding. GHC infers the following types.
*Orexio.Radix> :i query
query :: Data a => JSValue -> Result a
*Orexio.Radix> :i binding
binding ::
(Data (Representation a), Endpoint a, Resource a) =>
Result a -> Either String JSValue
Your error is essentially caused by the expression \x -> binding (query x) in the definition of bind. Notice that the type variable a appears only in the domain of binding and the range of query. Thus, when you compose them, two things happen.
The type variable is not determined; its "value" remains unknown.
The type variable is not reachable from the type of the
composition. For our informal purposes, that type is JSValue -> Either
String JSValue.
GHC raises the error because the type variable was not determined during the composition (ie 1) and it can never be determined in the future (a consequence of 2).
The general shape of this problem in Haskell is more commonly known as the "show-read problem"; search for "ambiguous" on Chapter 6 of Real World Haskell. (Some might also call it "too much polymorphism".)
As you and Sjoerd have determined (and the RWH chapter explains), you can fix this type error by ascribing a type to the result of query before applying binding. Without knowing your semantics, I assume that you intend this "hidden" type variable a to be the same as the argument to the Binding type constructor. So the following would work.
bind :: forall b.
(Data b, Resource b, Endpoint b, Data (Representation b)) => Binding b
bind = Binding (\x -> binding $ (query x :: Result b))
This ascription eliminates the type variable a by replacing it entirely with Result b. Note that unlike a it is acceptable for b to remain undetermined, since it's reachable in the top-level type; uses of bind may each determine b.
That first solution requires giving bind an explicit signature — which can sometimes be quite onerous. In this case, due to the monomorphism restriction, you probably already need that type signature. However, if bind took an argument (but still exhibited this ambiguous type variable error), you could still rely on type inference by using a solution like the following.
dummy_ResultType :: Binding a -> Result a
dummy_ResultType = error "dummy_ResultType"
bind () = result where
result = Binding (\x -> binding $ (query x `asTypeOf` dummy))
dummy = dummy_ResultType result
(If the use of error worries you, cf the Proxy type.)
Or trade some idiomaticness for directness:
withArgTypeOf :: f x -> g x -> f x
withArgTypeOf x _ = x
bind () = result where
result = Binding (\x -> binding (query x `withArgTypeOf` result))
Now inference works.
*Orexio.Radix> :i bind
bind ::
(Data (Representation a), Data a, Endpoint a, Resource a) =>
() -> Binding a
Rest assured that GHC quickly determines after typechecking that the definition is not actually recursive.
HTH.
I would like to release a resource when any exception is raised during the usage of the resource.
In C++ this task is easy: I put the release into the destructor, which gets called automatically, whatever happens. In Java one uses the 'finally' clause. What is the practice for this same task in Standard ML?
I tried to catch all exception with a variable pattern 'e' and re-raise it:
datatype FileReadResult = FileReadOkay of string | FileReadError
fun read_file (file_path_string : string) : FileReadResult =
let
val istream = TextIO.openIn file_path_string
(* this file is my resource *)
in
TextIO.closeIn istream;
FileReadOkay "" (* the content of the file will go here *)
handle e => (TextIO.closeIn istream; raise e)
end
handle Io => FileReadError
My compiler (MLton) accepts it, but because I am new in ML, I ask here for some assurance that this is really the right thing | best practice to do.
As this is a common design pattern, I created the below utility function to express it:
(* Uses the given resource in the given way while releasing it if any exception occurs. *)
fun use_resource (resource : 'Resource) (releaser : 'Resource -> unit) (usage : unit -> 'Result) : 'Result =
let
val r = usage ()
in
releaser resource;
r
end
handle e => (releaser resource; raise e)
This function plays the same role as the 'using' feature in C#.
Yes, that's the usual pattern, with two caveats:
The inner handle is around the FileReadOkay "" only in your code, which won't ever throw. You want to put parentheses around a larger part of the code, so that the handler applies to all of it.
Your outer handler catches Io. I think you mean IO.Io _ here, otherwise you will catch every exception (because Io is just a random fresh variable).
You can also try to abstract it into a function if it occurs frequently. Something along the lines of
(* withTextFile : string -> (TextIO.instream -> 'a) -> 'a
fun withTextFile name f =
let
val is = TextIO.openIn name
in
(f is before TextIO.closeIn is)
handle e => (TextIO.closeIn is; raise e)
end
(The infix operator before evaluates its left-hand and right-hand expression and returns the result of the former). Use it like:
fun echo file = withTextFile file (fn is => print(TextIO.inputAll is))