I am new to haskel.What would be a good way of doing something like this in haskell?
var1 = //can be true or false
if(var1==true)
{
//return someething
}
else
{
//
}
Haskell is a functional and declarative language. That means that usually that there is not much "do something". There is more calculate something and return it.
That may look like nitpicking, but for instance in Haskell one cannot set a variable twice: once you assign it an expression (not per se a value)
, you cannot set it to a different value.
If you want to return something, you usually work with pattern matching. For instance:
f :: Bool -> String
f True = "Yes"
f False = "No"
This would be somewhat equivalent in Java/C#/... to:
public String f (boolean var1) {
if(var1) {
return "Yes";
} else {
return "No";
}
}
Note that Haskell works lazy as well: if you return a function call or anything, you do not immediately evaluate that function call: a call is only evaluated if that is necessary.
A problem might arise how to do I/O. For that, there is the concept of an I/O monad. A monad is a functional programming technique that enforces a certain order of evaluation.
But functional programming thus requires a different "mindset" than imperative programming: you do not think of a program in terms of commands that are done one after another, but more in terms of composing functions together to generate output for a given input. Like usually a mathematician or physicist does. You compose for instance a function that, given the mass and the velocity of something, calculates the kinetic energy of that object.
Haskell has if-then-else conditionals.
The closest code to yours I can write is something like this:
let var = length "hello" == 5
in if var then "ok" else "no"
Note that such conditional is more similar to C or Java's var ? "ok" : "no" expression than an if()... statement, but this is to be expected since Haskell is functional, so it has no "statements", only expressions.
Any Haskell tutorial should cover this. I'd recommend you read one, if you want to learn Haskell. Trying to convert idioms from other languages is a poor strategy.
Related
Haskell is sometimes said to "replace equals for equals". The following code shows this isn't true under every interpretation of such a sentence. Wikipedia follows that by saying f(x)=f(x) for every x but that doesn't seem to carry any actual logical content one can test, it would be true by the reflexive law, a tautology.
I think the phrasing needed to make a logical claim like this is more like Leibniz' law (or indistinguishable identicals) where
x=y implies for every f, f(x)=f(y). That claim fails in the illustration below within Haskell. (We override == to make a partition type, but our function definition can freely ignore this and do.)
My question is, can one actually state referential transparency in a way that can be logically tested, and does Haskell actually uphold that logical claim?
module Main (main) where
data Floop = One | Two | Three
instance Eq Floop where
One == One = True
One == Two = False
One == Three = False
Two == One = False
Two == Two = True
Two == Three = True --- 2=3
Three == One = False
Three == Two = True --- 3=2
Three == Three = True
shuffle :: Floop -> Floop
shuffle One = Two
shuffle Two = Two --- fix 2
shuffle Three = One --- move 3
main = print ( (Two == Three) && (shuffle Two /= shuffle Three) )
--- prints "True" proving Haskell violates Leibniz Law
Expanding slightly on what I already said in my comment (thanks #FyodorSolkin for the prod):
You haven't violated referential transparency there, you've just made a pathological Eq instance.
While, as you've observed, the language doesn't forbid you from doing this, nor does it forbid one from making unlawful Functor or Monad instances. (Because it would be totally unfeasible to try to check these laws in practice.) But just because something doesn't cause a compiler error doesn't necessarily mean it's the right thing to do.
So the problem with your example is that while, semantically, (==) in Haskell indeed means "equal", it's just a function, in fact a method of a typeclass - which you can therefore implement however you want. Nothing stops me from defining, for example:
instance (Eq) (a -> b) where
_ == _ = True
and suddenly all functions will be considered "equal" under this definition. Clearly referential transparency will be violated if we consider this to be a true definition of equality. My point is that it's not. In fact it's quite obvious what "equality" means for any type which isn't either a function or otherwise depends on or "contains" function types. (It's actually obvious what equality of functions should mean too, it's just impossible for there to be a general algorithm to determine if two arbitrary functions are equal.)
[EDIT: I just remembered it also doesn't make much sense to talk about equality of IO actions. There might be some other abstract types like that where there's no clear definition of what equality would mean.]
To stray into abstract mathematics for a minute: your Eq instance certainly defines an equivalence relation, which is considered to be a sort of "generalised equality" - and indeed is equality if you use the relation to make equivalence classes. But then it's nonsense to try to apply a function to such a domain/type which differs on different elements of the same equivalence class. Such a thing - as in your example - actually fundamentally fails to be a well-defined mathematical function, because you're defining it on the individual elements in a way which fails to respect the equivalence relation.
f(x)=f(x) for every x
is by no means a tautology. In many popular languages, this property does not hold. Consider Java, for instance:
import java.util.*;
public class Transparency {
static int f(List<Object> xs) {
xs.add(xs.size());
return xs.size();
}
public static void main(String[] args) {
List<Object> x = new ArrayList<>();
System.out.println("Is java referentially transparent? " + (f(x) == f(x)));
}
}
$ javac Transparency.java
$ java Transparency
Is java referentially transparent? false
Here, because f mutates its input x, it would change behavior if we substitute x's definition into f(x) == f(x): f(new ArrayList<>()) == f(new ArrayList<>()) is in fact true, but when using a variable to reduce duplication it evaluates to false. In Haskell, such a substitution is always valid (disregarding cheats like unsafePerformIO).
In Haskell, afaik, there are no statements, just expressions. That is, unlike in an imperative language like Javascript, you cannot simply execute code line after line, i.e.
let a = 1
let b = 2
let c = a + b
print(c)
Instead, everything is an expression and nothing can simply modify state and return nothing (i.e. a statement). On top of that, everything would be wrapped in a function such that, in order to mimic such an action as above, you'd use the monadic do syntax and thereby hide the underlying nested functions.
Is this the same in OCAML/F# or can you just have imperative statements?
This is a bit of a complicated topic. Technically, in ML-style languages, everything is an expression. However, there is some syntactic sugar to make it read more like statements. For example, the sample you gave in F# would be:
let a = 1
let b = 2
let c = a + b
printfn "%d" c
However, the compiler silently turns those "statements" into the following expression for you:
let a = 1 in
let b = 2 in
let c = a + b in
printfn "%d" c
Now, the last line here is going to do IO, and unlike in Haskell, it won't change the type of the expression to IO. The type of the expression here is unit. unit is the F# way of expressing "this function doesn't really have result" in the type system. Of course, if the function doesn't have a result, in a purely functional language it would be pointless to call it. The only reason to call it would be for some side-effect, and since Haskell doesn't allow side-effects, they use the IO monad to encode the fact the function has an IO producing side-effect into the type system.
F# and other ML-based languages do allow side-effects like IO, so they have the unit type to represent functions that only do side-effects, like printing. When designing your application, you will generally want to avoid having unit-returning functions except for things like logging or printing. If you feel so inclined, you can even use F#'s moand-ish feature, Computation Expressions, to encapsulate your side-effects for you.
Not to be picky, but there's no language OCaml/F# :-)
To answer for OCaml: OCaml is not a pure functional language. It supports side effects directly through mutability, I/O, and exceptions. In many cases it treats such constructs as expressions with the value (), the single value of type unit.
Expressions of type unit can appear in a sequence separated by ;:
let s = ref 0 in
while !s < 10 do
Printf.printf "%d\n" !s; (* This has type unit *)
incr s (* This has type unit *)
done (* The while as a whole has type unit *)
Update
More specifically, ; ignores the value of the first expression and returns the value of the second expression. The first expression should have type unit but this isn't absolutely required.
# print_endline "hello"; 44 ;;
hello
- : int = 44
# 43 ; 44 ;;
Warning 10: this expression should have type unit.
- : int = 44
The ; operator is right associative, so you can write a ;-separated sequence of expressions without extra parentheses. It has the value of the last (rightmost) expression.
To answer the question we need to define what is an expression and what is a statement.
Distinction between expressions and statements
In layman terms, an expression is something that evaluates (reduces) to a value. It is basically something, that may occur on the right-hand side of the assignment operator. Contrary, a statement is some directive that doesn't produce directly a value.
For example, in Python, the ternary operator builds expressions, e.g.,
'odd' if x % 2 else 'even'
is an expression, so you can assign it to a variable, print, etc
While the following is a statement:
if x % 2:
'odd'
else:
'even'
It is not reduced to a value by Python, it couldn't be printed, assigned to a value, etc.
So far we were focusing more on the semantical differences between expressions and statements. But for a casual user, they are more noticeable on the syntactic level. I.e., there are places where a statement is expected and places where expressions are expected. For example, you can put a statement to the right of the assignment operator.
OCaml/Reason/Haskell/F# story
In OCaml, Reason, and F# such constructs as if, while, print etc are expressions. They all evaluate to values and can occur on the right-hand side of the assignment operator. So it looks like that there is no distinction between statements and expressions. Indeed, there are no statements in OCaml grammar at all. I believe, that F# and Reason are also not using word statement to exclude confusion. However, there are syntactic forms that are not expressions, for example:
open Core_kernel
it is not an expression, definitely, and
type students = student list
is not an expression.
So what is that? In the OCaml parlance, they are called definitions, and they are syntactic constructs that can appear in the module on the, so called, top-level. For example, in OCaml, there are value definitions, that look like this
let harry = student "Harry"
let larry = student "Larry"
let group = [harry; larry]
Every line above is a definition. And every line contains an expression on the right-hand side of the = symbol. In OCaml there is also a let expression, that has form let <v> = <exp> in <exp> that should not be confused with the top-level let definition.
Roughly the same is true for F# and Reason. It is also true for Haskell, that has a distinction between expressions and declarations. It actually should be true to probably every real-world language (i.e., excluding brainfuck and other toy languages).
Summary
So, all these languages have syntactic forms that are not expressions. They are not called statements per se, but we can treat them as statements. So there is a distinction between statements and expressions. The main difference from common imperative languages is that some well-known statements (e.g., if, while, for) are expressions in OCaml/F#/Reason/Haskell, and this is why people commonly say that there is no distinction between expressions and statements.
I'd like to ask what is the general opinion about using 2 Ternary operators instead of an if/else block for 2 variables.
Giving an example to make it clearer,
The if/else block:
var foo;
var bar;
if (boolean_expression) {
foo = value1;
bar = value2;
} else {
foo = value3;
bar = value4;
}
Using 2 Ternary Operations:
var foo = (boolean_expression) ? value1 : value3;
var bar= (boolean_expression) ? value2 : value4;
Obviously the if/else block is more efficient, since it only evaluates the boolean_expression once, whereas the 2 ternary operations evaluate it twice.
However, using ternary operations is, in my opinion, so much cleaner and readable, that I've recently decided on sacrificing the minimal efficiency difference between the two of them to improve my code's readability. (Provided the code isn't critical or executed too frequently)
Also, I would weakly argue the same for 3 variables.
Am I doing a horrible thing to my code, or is there a better way I'm not aware?
I'm coding in c#, but I guess this question matters for any language that has the ternary operation.
I guess this question matters for any language that has the ternary
operation
Some languages provide this:
(foo, bar) = (boolean_expression) ? (value1, value2) : (value3, value4);
The following scenario shows an abstraction that seems to me to be impossible to implement declaratively.
Suppose that I want to create a Symbol object which allows you to create objects with strings that can be compared, like Symbol.for() in JavaScript. A simple implementation in JS might look like this:
function MySymbol(text){//Comparable symbol object class
this.text = text;
this.equals = function(other){//Method to compare to other MySymbol
return this.text == other.text;
}
}
I could easily write this in a declarative language like Haskell:
data MySymbol = MySymbol String
makeSymbol :: String -> MySymbol
makeSymbol s = MySymbol s
compareSymbol :: MySymbol -> MySymbol -> Bool
compareSymbol (MySymbol s1) (MySymbol s2) = s1 == s2
However, maybe in the future I want to improve efficiency by using a global registry without changing the interface to the MySymbol objects. (The user of my class doesn't need to know that I've changed it to use a registry)
For example, this is easily done in Javascript:
function MySymbol(text){
if (MySymbol.registry.has(text)){//check if symbol already in registry
this.id = MySymbol.registry.get(text);//get id
} else {
this.id = MySymbol.nextId++;
MySymbol.registry.set(text, this.id);//Add new symbol with nextId
}
this.equals = function(other){//To compare, simply compare ids
return this.id == other.id;
}
}
//Setup initial empty registry
MySymbol.registry = new Map();//A map from strings to numbers
MySymbol.nextId = 0;
However, it is impossible to create a mutable global registry in Haskell. (I can create a registry, but not without changing the interface to my functions.)
Specifically, these three possible Haskell solutions all have problems:
Force the user to pass a registry argument or equivalent, making the interface implementation dependent
Use some fancy Monad stuff like Haskell's Control.Monad.Random, which would require either foreseeing the optimization from the start or changing the interface (and is basically just adding the concept of state into your program and therefore breaks referential transparency etc.)
Have a slow implementation which might not be practical in a given application
None of these solutions allow me to sufficiently abstract away implementation from my Haskell interface.
So, my question is: Is there a way to implement this optimization to a Symbol object in Haskell (or any declarative language) without causing one of the three problems listed above,
and are there any other situations where an imperative language can express an abstraction (for example an optimization like above) that a declarative language can't?
The intern package shows how. As discussed by #luqui, it uses unsafePerformIO at a few key moments, and is careful to hide the identifiers produced during interning.
In some dynamic languages I have seen this kind of syntax:
myValue = if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
3;
}
Basically being able to return the last statement in a branch as the return value for a variable, not necessarily only for method returns, but they could be achieved as well.
What's the name of this feature?
Can this also be achieved in staticly typed languages such as C#? I know C# has ternary operator, but I mean using if statements, switch statements as shown above.
It is called "conditional-branches-are-expressions" or "death to the statement/expression divide".
See Conditional If Expressions:
Many languages support if expressions, which are similar to if statements, but return a value as a result. Thus, they are true expressions (which evaluate to a value), not statements (which just perform an action).
That is, if (expr) { ... } is an expression (could possible be an expression or a statement depending upon context) in the language grammar just as ?: is an expression in languages like C, C# or Java.
This form is common in functional programming languages (which eschew side-effects) -- however, it is not "functional programming" per se and exists in other language that accept/allow a "functional like syntax" while still utilizing heavy side-effects and other paradigms (e.g. Ruby).
Some languages like Perl allow this behavior to be simulated. That is, $x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x will display "hello world!" because the eval expression evaluates to the last value evaluated inside even though the if grammar production itself is not an expression. ($x = if ... is a syntax error in Perl).
Happy coding.
To answer your other question:
Can this also be achieved in staticly typed languages such as C#?
Is it a thing the language supports? No. Can it be achieved? Kind of.
C# --like C++, Java, and all that ilk-- has expressions and statements. Statements, like if-then and switch-case, don't return values and there fore can't be used as expressions. Also, as a slight aside, your example assigns myValue to either a string or an integer, which C# can't do because it is strongly typed. You'd either have to use object myValue and then accept the casting and boxing costs, use var myValue (which is still static typed, just inferred), or some other bizarre cleverness.
Anyway, so if if-then is a statement, how do you do that in C#? You'd have to build a method to accomplish the goal of if-then-else. You could use a static method as an extension to bools, to model the Smalltalk way of doing it:
public static T IfTrue(this bool value, Action doThen, Action doElse )
{
if(value)
return doThen();
else
return doElse();
}
To use this, you'd do something like
var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
Disclaimer: I tested none of that, so it may not quite work due to typos, but I think the principle is correct.
The new IfTrue() function checks the boolean it is attached to and executes one of two delegates passed into it. They must have the same return type, and neither accepts arguments (use closures, so it won't matter).
Now, should you do that? No, almost certainly not. Its not the proper C# way of doing things so it's confusing, and its much less efficient than using an if-then. You're trading off something like 1 IL instruction for a complex mess of classes and method calls that .NET will build behind the scenes to support that.
It is a ternary conditional.
In C you can use, for example:
printf("Debug? %s\n", debug?"yes":"no");
Edited:
A compound statement list can be evaluated as a expression in C. The last statement should be a expression and the whole compound statement surrounded by braces.
For example:
#include <stdio.h>
int main(void)
{
int a=0, b=1;
a=({
printf("testing compound statement\n");
if(b==a)
printf("equals\n");
b+1;
});
printf("a=%d\n", a);
return 0;
}
So the name of the characteristic you are doing is assigning to a (local) variable a compound statement. Now I think this helps you a little bit more. For more, please visit this source:
http://www.chemie.fu-berlin.de/chemnet/use/info/gcc/gcc_8.html
Take care,
Beco.
PS. This example makes more sense in the context of your question:
a=({
int c;
if(b==a)
c=b+1;
else
c=a-1;
c;
});
In addition to returning the value of the last expression in a branch, it's likely (depending on the language) that myValue is being assigned to an anonymous function -- or in Smalltalk / Ruby, code blocks:
A block of code (an anonymous function) can be expressed as a literal value (which is an object, since all values are objects.)
In this case, since myValue is actually pointing to a function that gets invoked only when myValue is used, the language probably implements them as closures, which are originally a feature of functional languages.
Because closures are first-class functions with free variables, closures exist in C#. However, the implicit return does not occur; in C# they're simply anonymous delegates! Consider:
Func<Object> myValue = delegate()
{
if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
return this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
return 3;
}
};
This can also be done in C# using lambda expressions:
Func<Object> myValue = () =>
{
if (this.IsValidObject) { ... }
else { ... }
};
I realize your question is asking about the implicit return value, but I am trying to illustrate that there is more than just "conditional branches are expressions" going on here.
Can this also be achieved in staticly
typed languages?
Sure, the types of the involved expressions can be statically and strictly checked. There seems to be nothing dependent on dynamic typing in the "if-as-expression" approach.
For example, Haskell--a strict statically typed language with a rich system of types:
$ ghci
Prelude> let x = if True then "a" else "b" in x
"a"
(the example expression could be simpler, I just wanted to reflect the assignment from your question, but the expression to demonstrate the feature could be simlpler:
Prelude> if True then "a" else "b"
"a"
.)