http://hackage.haskell.org/package/base-4.6.0.1/docs/src/GHC-Base.html#assert seems to define assert to be a no-op. Where's the logic that turns this into something else when assertions are enabled?
The comment above that function gives a hint:
-- Assertion function. This simply ignores its boolean argument.
-- The compiler may rewrite it to #('assertError' line)#.
So, just use github code search and search for assertError: search results
This turns up the file RnExpr.lhs. Searching for assert in this file, you'll find the following code:
finishHsVar :: Name -> RnM (HsExpr Name, FreeVars)
-- Separated from rnExpr because it's also used
-- when renaming infix expressions
-- See Note [Adding the implicit parameter to 'assert']
finishHsVar name
= do { this_mod <- getModule
; when (nameIsLocalOrFrom this_mod name) $
checkThLocalName name
; ignore_asserts <- goptM Opt_IgnoreAsserts
; if ignore_asserts || not (name `hasKey` assertIdKey)
then return (HsVar name, unitFV name)
else do { e <- mkAssertErrorExpr
; return (e, unitFV name) } }
That's where it replaces assert by assertError, but only if assertions are enabled.
assertError is defined in GHC.IO.Exception
Related
With MiniZinc, is there a way to print out the programmatically-generated constraints? For example:
constraint exists (i in 1..3) (
foo != i
);
I want to confirm that it is generating:
constraint (foo != 1 \/ foo != 2 \/ foo !=3);
Although MiniZinc doesn't offer direct printing of constraints as such. MiniZinc does offer the trace(string: s, var $T: expr) function. Which can be used to debug your MiniZinc models. trace is a print-statement that prints its contents to the command line at the time of evaluation within the compiler. It can thus be used to print the information that you wish to see, but you'll have to format it yourself to show the constraints.
In the case of your exists loop you could use:
constraint exists(i in 1..3) (
trace("foo != \(i)" ++ if i != max(1..3) then " \\/ " else "\n" endif,
foo != i)
);
This will print foo != 1 \/ foo != 2 \/ foo != 3 to the command line.
To get to know the generated constraints, you can have a look at the generated FlatZinc file. The MiniZinc compiler translates the MiniZinc source into FlatZinc. This is then handed over to a solver back-end like Gecode of Chuffed.
MiniZinc input:
var int: foo;
constraint exists (i in 1..3) (
foo != i
);
solve satisfy;
Created FlatZinc:
var int: foo:: output_var;
var bool: X_INTRODUCED_0_ ::var_is_introduced :: is_defined_var;
var bool: X_INTRODUCED_1_ ::var_is_introduced :: is_defined_var;
var bool: X_INTRODUCED_2_ ::var_is_introduced :: is_defined_var;
constraint array_bool_or([X_INTRODUCED_2_,X_INTRODUCED_1_,X_INTRODUCED_0_],true);
constraint int_ne_reif(foo,1,X_INTRODUCED_0_):: defines_var(X_INTRODUCED_0_);
constraint int_ne_reif(foo,2,X_INTRODUCED_1_):: defines_var(X_INTRODUCED_1_);
constraint int_ne_reif(foo,3,X_INTRODUCED_2_):: defines_var(X_INTRODUCED_2_);
solve satisfy;
To look at the FlatZinc form, you can add parameter --output-fzn-to-stdout in the Configuration tab of the MiniZinc IDE:
MiniZinc goes through a whole series of steps when it compiles your expressions down to FlatZinc, so it's not so easy to decide after which step you would print the intermediate representation of the problem.
To look at the generated FlatZinc, you can also simply select "Compile" from the MiniZinc menu rather than using the --output-fzn-to-stdout command line option.
I need to do something similar to bar = (foo == null) ? null : foo.bar
Is Null Propagation Operator (?.) available in Node.js? If no, Is this a proposal for the newer version?
[Edit] To add more clarity, I want to avoid NPE when accessing foo.bar (when foo is not defined) and the expression should return a null instead.
Update based on below comment:
The below code will evaluate to the value of foo if foo is falsey (null, undefined, false, empty string, etc), or to foo.bar if foo is not falsey. Like the || operator, the && operator also returns whatever it evaluates last. If foo is falsey, then it will abort evaluation and return the value of foo. If foo is not falsey, then it will continue and evaluate foo.bar and return whatever that is.
foo && foo.bar
Original answer:
You can accomplish this in Javascript using the or operator, ||
The or operator does not necessarily evaluate to a boolean. It returns the last argument that it evaluates the truthiness of.
So, building off of your example, the following code sets foo equal to foo.bar.
foo = null || foo.bar
And the following compares foo to foo.bar (I'm not sure if the double =s in your code was intentional or not. If it was intentional, then consider using triple =s instead)
foo === (null || foo.bar)
This concept is frequently used for setting default values. For example, a function that takes an options argument may do something like this.
options.start = options.start || 0;
options.color = options.color || "red";
options.length = options.length || 10;
Just be careful of one thing. In the last line of the above code, if options.length is 0, then it will be set to 10, because 0 evaluates to false. In that scenario, you probably want to do things the "old-fashioned" way:
options.length = options.length === undefined ? 10 : options.length;
const bar = foo && foo.bar;
This is called Short-circuit evaluation, where second part (part after &&) is only evaluated if the first part is a truthy value.
JavaScript has added support for this, It's called Optional Chaining.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
I'm currently working my way through Learn You a Haskell for Great Good, and I'm trying to modify one of the code snippets in chapter nine, "Input and Output" to handle errors correctly:
main = do
(command:args) <- getArgs
let result = lookup command dispatch
if result == Nothing
then
errorExit
else
let (Just action) = result
action args
where
dispatch :: [(String, [String] -> IO ())]
is an association list
and
errorExit :: IO ()
is some function that prints an error message.
Compiling this with GHC gives the error message
todo.hs:20:13: parse error in let binding: missing required 'in'
which (to my understanding), seems to be saying that the "let" here doesn't realise it's in a "do" block.
Adding "do" on lines five and seven (after "then" and "else" respectively), changes the error message to
todo.hs:20:13:
The last statement in a 'do' block must be an expression
let (Just action) = result
todo.hs:21:5: Not in scope: `action'.
and now, whilst I agree with the first error message, I also have that one of my variables has jumped out of scope? I've double checked my alignment, and nothing seems to be out of place.
What is the appropriate way to assign a varaible within an if clause that is within a do block?
My suggestion is to not use if in the first place, use case. By using case you get to test the value and bind the result to a variable all in one go. Like this:
main = do
(command:args) <- getArgs
case lookup command dispatch of
Nothing -> errorExit
Just action -> action args
For a more in-depth discussion on why we should prefer case over if see boolean blindness.
#svenningsson suggested the right fix. The reason your original fails is because let clauses can only appear at the top level of a do block - they're simple syntactic sugar that doesn't look into inner expressions:
do let x = 1
y
desugars to the let expression
let x = 1 in y
Alas, in a do block, an expression clause like if ... then ... else ... has no way to declare variables in the rest of the do block at all.
There are at least two possible ways to get around this.
Absorb the remainder of the do block into the expression:
main = do
(command:args) <- getArgs
let result = lookup command dispatch
if result == Nothing
then
errorExit
else do
let (Just action) = result
action args
(This is essentially the method #svenningsson uses in his better case version too.)
This can however get a bit awkward if the remainder of the do expression needs to be duplicated into more than one branch.
("Secret" trick: GHC (unlike standard Haskell) doesn't actually require a final, inner do block to be indented more than the outer one, which can help if the amount of indentation starts getting annoying.)
Pull the variable declaration outside the expression:
main = do
(command:args) <- getArgs
let result = lookup command dispatch
action <- if result == Nothing
then
errorExit
else do
let (Just action') = result
return action'
action args
Here that requires making up a new variable name, since the pattern in the let clause isn't just a simple variable.
Finally, action was always out of scope in the last line of your code, but GHC works in several stages, and if it aborts in the parsing stage, it won't check for scope errors. (For some reason it does the The last statement in a 'do' block must be an expression check at a later stage than parsing.)
Addendum: After I understood what #Sibi meant, I see that result == Nothing isn't going to work, so you cannot use if ... then ... else ... with that even with the above workarounds.
You are getting an error because you are trying to compare values of function type. When you perform the check if result == Nothing, it tries to check the equality of Nothing with the value of result which is a type of Maybe ([String] -> IO ()).
So, if you want it to properly typecheck, you have to define Eq instances for -> and that wouldn't make any sense as you are trying to compare two functions for equality.
You can also use fmap to write your code:
main = do
(command:args) <- getArgs
let result = lookup command dispatch
print $ fmap (const args) result
Can I always expect the single single-quote syntax to desugar to the NameG constructor? e.g. does
'x
always desugar to
(Name (OccName "x") (NameG VarName (PkgName "some-package") (ModName "SomeModule")))
This information must always be there, after name resolution, which is the stage Template Haskell runs after, right? And I haven't been able to quote local names, though I'm only interested in quoting top-level names.
Context: I want to write a function that returns the uniquely-qualified identifier. It's a partial function because I can't constrain the input, as Template Haskell doesn't have any GADTs or anything, while I don't want to wrap the output in uncertainty. And I don't want to use a quasi-quoter or splice, if ' will do. I want to prove that this partial function is safe at runtime when used as above, quoting top-level names in the same module, given:
name (Name occ (NameG _ pkg mod)) = Unique occ pkg mod
I want to have a function like:
(<=>) :: Name -> a -> Named a
given:
data Named a = Named a Unique
to annotate variable bindings:
x = 'x
<=> ...
without the user needing to use the heavy splice syntax $(name ...), and invoke splicing at compile time:
x = $(name 'x)
<=> ...
The user will be writing a lot of these, for configuration.
https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/template-haskell.html and https://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/src/Language-Haskell-TH-Syntax.html#Name didn't say.
(p.s. I'd also like to know if the double single-quote syntax (e.g. ''T) had the analogous guarantee, though I'd expect them to be the same).
Since ' quoted names are known at compile time, why don't you change name to be in the Q monad:
name :: Name -> ExpQ
name (Name occ (NameG _ pkg mod)) = [| Unique occ pkg mod |]
name n = fail $ "invalid name: "++ gshow n
Then you use $(name 'show) :: Unique instead of name 'show :: Unique. If you get an invalid Name (say somebody uses mkName), that failure will show up at compile time.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
The error must be so tiny in these few lines that I will not get it myselft.
Here is my code:
askName = do
putStr "Type your name: "
name <- getLine
return name
sayHelloTo name = do
when (null name) (name <- askName)
Apparently it gives an error:
1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:9:30: parse error on input `<-'
Failed, modules loaded: none.
Any suggestion?
Edit 1.
Same if I write:
sayHelloTo name = do
when (null name) (name2 <- askName)
The name2 <- syntax is part of do-notation and can only be used inside a do block. It is also not a variable assignment - under the hood it is just creating a callback function that has name2 as a parameter
That is, the following code:
do
name2 <- monadicOp
...things...
desugars into
monadicOp >>= (\name2 -> ...things... )
I hope this helps make it clear that you don't assign things or mutate them in Haskell.
anyway, to solve your particular problem, whay you could do is just use if-then-else (something that is actually equivalent to the ?: ternary oerator) and return the appropriate value. For example, the following function uses recursion to ask for a name again and again until it is happy with the result
getNonEmptyName :: IO String
getNonEmptyName = do
name <- getName
if null name --note: indenting if statements in do blocks is tricky
then getNonEmptyName
else (return name)
or, without the do notation sugar:
getNonEmptyName = getName >>= (\name -> if (null name) then getNonEmptyName else (return name) )
This might be a bit moe different the what you are used to, but I guess you should be able to clear thing sup after you get how this is working. Basically getNonEmptyName is of type IO String, meaning it is an IO actioin IO action that yields a String when it is run. The if-then-else part is supposed to evaluate to an IO String value as well, since its value will be the return value of getNonEmptyName. This all works all right since in the first we do a recursive call to getNonEmptyName (and that gives an IP String value as desired) and in the else branch we promote a regular string value (name) to an IO String using the return function.
It's not entirely clear what sayHelloTo is supposed to do or return -- it's certainly not going to modify name -- but at a guess, you might mean something like
sayHelloTo :: String -> IO String
sayHelloTo name
| null name = askName
| otherwise = return name