Why does unsafePartial not work with a simple functor in PureScript? - functor

Unless I've made some simple error, the following pieces of code should be functionally identical:
-- This code does not compile
pg :: forall a. PG a -> Route a
pg sql = connect $ apply (runPG sql) (unsafePartial <<< fromJust <$> getConnection)
-- This code does not compile
pg sql = connect $ do
connection <- unsafePartial <<< fromJust <$> getConnection
runPG sql connection
-- This code does work
pg sql = connect $ do
connection <- getConnection
runPG sql $ unsafePartial $ fromJust connection
To help understand this, here are the relevant types:
-- Route has a MonadAff instance and all the usual stuff
newtype Route a = Route (ReaderT RouteState Aff a)
-- `connect` makes a connection to Postgres and injects it into the environment.
connect :: forall a. Route a -> Route a
getConnection :: Route (Maybe Connection)
-- PG has a MonadAff instance and all the usual stuff
newtype PG a = PG (ReaderT Connection Aff a)
runPG :: forall m a. MonadAff m => PG a -> Connection -> m a
Here is the error:
Error found:
in module AWS.Lambda.Router
at src/AWS/Lambda/Router.purs:176:70 - 176:83 (line 176, column 70 - line 176, column 83)
Could not match constrained type
Partial => t1
with type
{ client :: Client
, pool :: Pool
}
while trying to match type { client :: Client
, pool :: Pool
}
with type Partial => t1
while checking that expression getConnection
has type t0 (Maybe (Partial => t1))
in value declaration pg
where t0 is an unknown type
t1 is an unknown type
See https://github.com/purescript/documentation/blob/master/errors/ConstrainedTypeUnified.md for more information,
or to contribute content related to this error.
spago: Failed to build.
I think one of two things is going on here. Either I'm making some dumb syntax error or I don't understand Partial as I thought I did, although it seems pretty straightforward.

This happens because type inference doesn't work very well with constraints. It doesn't always know if it needs to move constraints to the top or leave them in place. In general this is an undecidable problem, the compiler just tries to make the best effort.
Try this in the REPL:
> :t fromJust
forall a. Partial => Maybe a -> a
> :t unsafePartial
forall a. (Partial => a) -> a
> :t unsafePartial <<< fromJust
forall t2. Partial => Maybe (Partial => t2) -> t2
See what happened? The function composition has "distributed" the Partial constraint over the parts of its argument, because it's not clear whether the constraint in fromJust applies to the whole type or individually to a. This might actually be a compiler bug, but it's hard to say for me right now.
So if you try to apply this function composition via <$> to getConnection, the compiler expects getConnection to have this weird doubly-nested type, which it doesn't.
Interestingly, you can use unsafePartial to remove the Partial constraint from the whole function fromJust, rather than just its return value:
> :t unsafePartial fromJust
forall t4. Maybe t4 -> t4
This means that you can do something like this:
pg :: forall a. PG a -> Route a
pg sql = connect $ bind (unsafePartial fromJust <$> getConnection) (runPG sql)

Related

F# using match to validate parameters

I'm learning F#. I want to know best practices for validating input parameters. In my naivety I had thought I could do something like this:
let foo = match bar with
| <test for valid> -> bar
| _ -> "invalid"
of course that doesn't work due to mismatching types. So I'd like to see the patterns experienced F# programmers use for this sort of thing. match? If/then/else?
Something else?
You are having problems because you are trying to bind a value to something that could be two possible types depending upon program flow - that is incompatible with static typing.
If I have some value foo, it cannot be, for example, a string OR an int depending upon program flow; it must resolve to exactly one type at compile time.
You can, however, use a discriminated union that can represent several different options within a single type.
Here is a summary of the approaches for doing just that.
Result Type / Either
F# 4.1, which is currently available via nuget, introduces the Result type. You may find this type referred to as Either in other languages.
It is defined like this:
[<Struct>]
type Result<'T,'TError> =
/// Represents an OK or a Successful result. The code succeeded with a value of 'T.
| Ok of ResultValue:'T
/// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong.
| Error of ErrorValue:'TError
If you are pre-F# 4.1 (which is very likely). You can define this type yourself, although you must remove the [<Struct>] attribute.
You can then make a tryParseFloat function:
let tryParseFloat str =
match System.Double.TryParse str with
| true, f -> Ok f
| _ -> Error <| sprintf "Supplied string (%s) is not a valid float" str
You can determine success or failure:
match tryParseFloat "0.0001" with
|Ok v -> // handle success
|Error err -> // handle error
In my opinion, this is the preferred option, especially in F# 4.1+ where the type is built in. This is because it allows you to include information relating to how and why some activity failed.
Option Type / Maybe
The option type contains either Some 'T or simply None. The option type is used to indicate the presence or absence of a value, None fills a role similar to null in other languages, albeit far more safely.
You may find this type referred to as Maybe in other languages.
let tryParseFloat str =
match System.Double.TryParse str with
| true, f -> Some f
| _ -> None
You can determine success or failure:
match tryParseFloat "0.0001" with
|Some value -> // handle success
|None -> // handle error
Composition
In both cases, you can readily compose options or results using the associated map and bind functions in the Option and Result modules respectively:
Map:
val map: mapping:('T -> 'U) -> option:'T option -> 'U option
val map : mapping:('T -> 'U) -> result:Result<'T, 'TError> -> Result<'U, 'TError>
The map function lets you take an ordinary function from 'a -> 'b and makes it operate on results or options.
Use case: combine a result with a function that will always succeed and return a new result.
tryParseFloat "0.001" |> Result.map (fun x -> x + 1.0);;
val it : Result<float,string> = Ok 1.001
Bind:
val bind: binder:('T -> 'U option) -> option:'T option -> 'U option
val bind: binder:('T -> Result<'U, 'TError>) -> result:Result<'T, 'TError> -> Result<'U, 'TError>
The bind function lets you combine results or options with a function that takes an input and generates a result or option
Use case: combine a result with another function that may succeed or fail and return a new result.
Example:
let trySqrt x =
if x < 0.0 then Error "sqrt of negative number is imaginary"
else Ok (sqrt x)
tryParseFloat "0.001" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> = Ok 0.0316227766
tryParseFloat "-10.0" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> = Error "sqrt of negative number is imaginary"
tryParseFloat "Picard's Flute" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> =
Error "Supplied string (Picard's Flute) is not a valid float"
Notice that in both cases, we return a single result or option despite chaining multiple actions - that means that by following these patterns you need only check the result once, after all of your validation is complete.
This avoids a potential readability nightmare of nested if statements or match statements.
A good place to read more about this is the Railway Oriented Programming article that was mentioned to you previously.
Exceptions
Finally, you have the option of throwing exceptions as a way of preventing some value from validating. This is definitely not preferred if you expect it to occur but if the event is truly exceptional, this could be the best alternative.
The basic way of representing invalid states in F# is to use the option type, which has two possible values. None represents invalid state and Some(<v>) represents a valid value <v>.
So in your case, you could write something like:
let foo =
match bar with
| <test for valid> -> Some(bar)
| _ -> None
The match construct works well if <test for valid> is actual pattern (e.g. empty list or a specific invalid number or a null value), but if it is just a boolean expression, then it is probably better to write the condition using if:
let foo =
if <test for valid> bar then Some(bar)
else None
You could do something along this lines
type Bar =
| Bar of string
| Foo of int
let (|IsValidStr|_|) x = if x = Bar "bar" then Some x else None
let (|IsValidInt|_|) x = if x = Foo 0 then Some x else None
let foo (bar:Bar) =
match bar with
| IsValidStr x -> Some x
| IsValidInt x -> Some x
| _ -> None
That is you could use active patterns to check for the actual business rules and return an Option instance
Based on what the OP wrote in the comments:
You would define a type as in the post that Fyodor linked, that captures your two possible outcomes:
type Result<'TSuccess,'TFailure> =
| Success of 'TSuccess
| Failure of 'TFailure
Your validation code becomes:
let checkBool str =
match bool.TryParse str with
| true, b -> Success b
| _ -> Failure ("I can't parse this: " + str)
When using it, again use match:
let myInput = "NotABool"
match checkBool myInput with
| Success b -> printfn "I'm happy: %O" b
| Failure f -> printfn "Did not like because: %s" f
If you only would like to continue with valid bools, your code can only fail on invalid arguments, so you would do:
let myValidBool =
match checkBool myInput with
| Success b -> b
| Failure f -> failwithf "I did not like the args because: %s" f

When generalizing monad, performance drops nearly 50%

I have code that does some parsing of files according to specified rules. The whole parsing takes place in a monad that is a stack of ReaderT/STTrans/ErrorT.
type RunningRule s a = ReaderT (STRef s LocalVarMap) (STT s (ErrorT String Identity)) a
Because it would be handy to run some IO in the code (e.g. to query external databases), I thought I would generalize the parsing, so that it could run both in Identity or IO base monad, depending on the functionality I would desire. This changed the signature to:
type RunningRule s m a = ReaderT (STRef s LocalVarMap) (STT s (ErrorT String m)) a
After changing the appropriate type signatures (and using some extensions to get around the types) I ran it again in the Identity monad and it was ~50% slower. Although essentially nothing changed, it is much slower. Is this normal behaviour? Is there some simple way how to make this faster? (e.g. combining the ErrorT and ReaderT (and possibly STT) stack into one monad transformer?)
To add a sample of code - it is a thing that based on a parsed input (given in C-like language) constructs a parser. The code looks like this:
compileRule :: forall m. (Monad m, Functor m) =>
-> [Data -> m (Either String Data)] -- For tying the knot
-> ParsedRule -- This is the rule we are compiling
-> Data -> m (Either String Data) -- The real parsing
compileRule compiled (ParsedRule name parsedlines) =
\input -> runRunningRule input $ do
sequence_ compiledlines
where
compiledlines = map compile parsedlines
compile (Expression expr) = compileEx expr >> return ()
compile (Assignment var expr) =
...
compileEx (Function "check" expr) = do
value <- expr
case value of
True -> return ()
False -> fail "Check failed"
where
code = compileEx expr
This is not so unusual, no. You should try using SPECIALIZE pragmas to specialize to Identity, and maybe IO too. Use -ddump-simpl and watch for warnings about rule left hand sides being too complicated. When specialization doesn't happen as it should, GHC ends up passing around typeclass dictionaries at runtime. This is inherently somewhat inefficient, but more importantly it prevents GHC from inlining class methods to enable further simplification.

How to make a table (Data.Map) strict in haskell?

For learning Haskell (nice language) I'm triying problems from Spoj.
I have a table with 19000 elements all known at compile-time.
How can I make the table strict with 'seq'?
Here a (strong) simplified example from my code.
import qualified Data.Map as M
-- table = M.fromList . zip "a..z" $ [1..] --Upps, incorrect. sorry
table = M.fromList . zip ['a'..'z'] $ [1..]
I think you're looking for deepseq in Control.DeepSeq which is used for forcing full evaluation of data structures.
Its type signature is deepseq :: NFData a => a -> b -> b, and it works by fully evaluating its first argument before returning the second.
table = t `deepseq` t
where t = M.fromList . zip ['a'..'z'] $ [1..]
Note that there is still some laziness left here. table won't get evaluated until you try to use it, but at that point the entire map will be evaluated.
Note that, as luqui pointed out, Data.Map is already strict in its keys, so doing this only makes sense if you want it to be strict in its values as well.
The general answer is, you write some code that must force evaluation of the whole datastructure. For example, if you have a list:
strictList xs = if all p xs then xs else []
where p x = x `seq` True
I am sure there is already some type class that would apply such forcing recursively and instances for standard data types.

composing many quotations into linq queries

I'm working on a project in which I'm trying to use F# and Linq for UDF's and stored procs in an SQL server.
Part of that has been to statically define all the valid queries, the sorting criteria, and a means of scoring the results of the queries.
I've so far been fairly successful, but I'm running into serious difficulty composing sortBy expressions.
Here's the basic concept
let sorter =
let exprMap:Map<string,Quotations.Expr<seq<Product> -> seq<Product>>> =
Map.ofList
["ProductName",<# Seq.sortBy (fun prod -> prod.Name) #> ]
// .. more entries ..
let sortBuilder sortkeys =
Array.foldBack
(fun criteria acc -> <# %(exprMap.[criteria]) >> (%acc) #>)
sortkeys
<# Seq.map id #>
This ends up being used later in the query executor like so
let execQuery = fun (predicates,sorts,scorer) ->
<# seq { for prod in (%dc).Products do
if (%predicates) prod then yield prod }
|> (%sorts)
|> (%scorer) #>
Using these basic outlines, everything works as long as I don't use (%sorts). Each time I pass that in, I get not recognized in F# to Linq translator. I've tried a number of different attempts at using combinators, but I have the sense I'm missing something. If I stub out the sorter function with the following
<# Seq.sortBy (fun prod -> prod.Name) |> Seq.sortBy (fun prod -> prod.Style) #>
It works as expected. However using a combinator like this:
let (|>*) = fun f g -> <# fun c -> ((%f) c) |> (%g) #>
does not..
Any ideas?
Unfortunately, I don't have any good answer to this question.
I'm afraid that the F# LINQ translator is currently very sensitive to the structure of the query. Using composition, you should be able to get the same quotation you get if you write it by hand, so you may need to generate exactly the same thing that worked if written by hand.
For example with your sorter, you may need something like (I didn't try it, but I think this should produce exactly the same quotation as the usual code that works):
let (|>*) f g = fun c -> <# (%c) |> (%f) |> (%g) #>
<# seq { for prod in (%dc).Products do
if (%predicates) prod then yield prod } #> |>
( <# Seq.sortBy (fun prod -> prod.Name) #> |>*
<# Seq.sortBy (fun prod -> prod.Style) #> )
The problem is that if you include lambda functions in the quotation, the F# translator needs to deal with them - probably by partially evaluating them (because otherwise the LINQ to SQL translator would fail). There are quite a few tricky cases in this...
However, the F# team has been doing some improvements in this area recently. I think the best thing to do would be to find a simple repro case and send it to fsbugs at microsoft dot com. PowerPack releases are not that "sensitive" so you may be able to get the source code with the recent changes if you ask and offer help with testing (but no promises).

Haskell: Can I use a where clause after a block with bind operators (>>=)?

I have a very simple question. I'd like to use a where clause after a bloc of code that uses bind operators but I get a compilation error.
Here is a simple example:
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
print list'
where list' = reverse list -- test1.hs:5:28: Not in scope: `list'
I can use a let clause for list' as in
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
let list' = reverse list -- works of course
in print list'
but I'd really like it if I could use a where clause...
I also tried with do notation
main = do
putStrLn "where clause test:"
list <- return [1..10]
print list'
where list' = reverse list --test3.hs:5:30: Not in scope: `list'
Same problem. Can I use a where clause in these circumstances?
As ephemient explains, you can't use where clauses the way you do.
The error happens because in this code:
main =
return [1..10] >>= \list ->
print list'
where
list' = reverse list
The where-clause is attached to the main function.
Here's that same function with more parentheses:
main = return [1..10] >>= (\list -> print list')
where
list' = reverse list
I think its fairly obvious why you get the "out of scope" error: The binding for list is deep inside the main expression, not something the where clause can reach.
What I usually do in this situation (and I've been bitten by the same thing a bunch of times). I simply introduce a function and pass the list as an argument.
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style
Of course, I imagine your actual code in the f function is a lot more that just reverse and that's why you want it inside a where clause, instead of an inline let binding. If the code inside the f function is very small, I'd just write it inside the let binding, and wouldn't go through the overhead of introducing a new function.
The problem is that let-in is an expression, which can be used inside other expressions, while where can only be used on a (module|class|instance|GADT|...) declaration or a (function|pattern) binding.
From the Haskell 98 report on declarations and bindings,
p | g1 = e1
| g2 = e2
…
| gm = em
where { decls }
is sugar for
p = let decls in
if g1 then e1 else
if g2 then e2 else
…
if gm then em else error "Unmatched pattern"
or, simplifying things by removing guards,
p = e where { decls }
is sugar for
p = let decls in e
in both function and pattern bindings. This is true even when your e is a do {…} construct.
If you want to have a binding local to a particular subexpression within a larger expression, you need to use let-in (or simply let inside a do, but that's just sugar for let-in).
You can't even write
main = do
putStrLn "where clause test: "
list <- return [1..10]
(print list' where list' = reverse list)
because "e where { decls }" is not a legal expression – where can only be used in declarations and bindings.
main = do
putStrLn "where clause test: "
list <- return [1..10]
let list' = list'' where list'' = reverse list
print list'
This is legal (if somewhat contrived).
As far as I can tell, the where clause is only used in local bindings. The inner part of a >>(=) binding statement is not a local binding (two different kinds of bindings in that sentence).
Compare with this:
main = f [1..10]
f list =
putStrLn "where clause test:" >> print list'
where list' = reverse list
You might want to refer to the Haskell 98 syntax report - not sure how much help it would be.
If I'm wrong, someone will certainly correct me, but I'm pretty sure you can't use a where clause at all in the style you've shown above. list will never be in scope to a where clause unless it's a parameter to the function.

Resources