What characters are allowed in Haskell function names? - haskell

What is a valid name for a function?
Examples
-- works
let µ x = x * x
let ö x = x * x
-- doesn't work
let € x = x * x
let § x = x * x
I am not sure, but my hunch is that Haskell doesn't allow Unicode function names, does it?
(Unicode like in http://www.cse.chalmers.se/~nad/listings/lib-0.4/Data.List.html)

From the Haskell report:
Haskell uses the Unicode character set. However, source programs are currently biased toward the ASCII character set used in earlier versions of Haskell .
Recent versions of GHC seem to be fine with unicode (at least in the form of UTF-8):
Prelude> let пять=5; два=2; умножить=(*); на=id in пять `умножить` на два
10
(In case you wonder, «пять `умножить` на два» means «five `multiplied` by two» in Russian.)
Your examples do not work because those character are «symbols» and can be used in infix operators but not in function names. See "uniSymbol" category in the report.
Prelude> let x € y = x * y in 2 € 5
10

Related

Haskell Add-Operation

In a Codefights challenge where you have to add two numbers the user kaiochao had a super minimalisic answer
add = (+)
How does it work and has this functionality a own name?
Here's an explicit definition:
add a b = a + b
There is a feature in Haskell that says that we can rewrite a + b as (+) a b, this is due to the fact that operators are functions in Haskell. So we can rewrite:
add a b = (+) a b
But then we're doing nothing extra to the arguments of this function, so we can reduce this function by removing the explicit arguments*. Note that this requires an understanding of how function application in Haskell works:
add = (+)
This is because functions are data in Haskell. This is literally saying that plus and the function of addition are the same thing.
In practice, we can see this by substituting:
add 1 2
= (+) 1 2 -- Since add = (+), this can be read literally.
= 1 + 2 -- This is how operators work in Haskell.
= 3 -- Calculation.
This is known as pointfree style in Haskell.
*As #Benjamin Hodgson mentioned, this is called eta-reduction.
This “functionality” is just variable assignment. It works the same way as writing
three = 3
3 is just a Haskell value, which I can at any point give a new name, refer to it, and get something that's (at least, at runtime) indistinguishable from 3 itself.
The fact that add has a somewhat more complicated type, namely a function type, changes nothing about the way such variable assignments work. I can certainly define
root = sqrt
...and then evaluate root 4 to obtain 2.0 as the result. Or, for any custom function,
foo :: Int -> String
foo n = concat $ replicate n (show n)
bar = foo
GHCi> bar 3
"333"
GHCi> bar 7
"7777777"
All that is really no different from how I can also write
Python 3.5.2 (default, Sep 14 2017, 22:51:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import math
In [2]: root = math.sqrt
In [3]: root(4)
Out[3]: 2.0
What's a bit more interesting about add is that + is an infix operator (because it consists of non-letter characters). But Haskell allows using such infix operators pretty much just as liberally as any other variables, including that you can define your own. The only thing that's a bit different are the parsing rules. + can not be a standalone syntactic unit but has to be surrounded on each side with with arguments you want to add, or with parentheses. The latter, (+), is really what the plus operator is from the compiler's point of view: the binary function, not yet applied to any arguments. So, when you want to give this operator a new name, you need to write
add = (+)
Incidentally, you could also give it a new operator-name, like
(⊕) = (+)
...that could then be used like 3 ⊕ 4, just as you can with the standard + operator.

Summation in Haskell - functional programing [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm having trouble writing a simple function in Haskell... It is meant to calculate the sum of numbers from 1 to n. I'm not allowed to use if statements because my teacher want us to focus on functional programing. Any help would be appreciated. Thanks!
summation :: Integer -> Integer
summation n
| n > 1 = n + summation(n-1)
| n == 1 = 1
This is the output from GHCi:
clase4.hs:13:28: error:
Variable not in scope: (?) :: Integer -> Integer -> Integer
Failed, modules loaded: none.
Line 13 is:
| n > 1 = n + summation(n-1)
I've commented everything else in the file and I still get that error. I cannot see '?' anywhere. These are the screen captures:
In your source file clase4.hs, the character you think is a standard ASCII minus sign in the expression n-1 isn't. Instead, you've probably used some other unicode character, like an "en dash" or something that only looks like a minus sign (perhaps because you've edited the file in something weird like Microsoft Word or copied and pasted the code from some source that was messing with the characters).
Haskell is printing the invalid character as a "?" because, as far as it can tell, your output terminal doesn't support the encoding necessary to display the bad character. (This is a common problem when running Haskell in a Windows environment, though it might happen on other platforms if things were set up strangely.)
Open the source file with a proper text editor, highlight the "minus sign" and re-type it on your keyboard. On a Spanish keyboard, this should be the key to the left of the bottom-right shift key; on a US keyboard, it's to the right of the zero key.
If that fails, try copying and pasting your own program above from Stack Overflow into a brand new text file and compile that -- copying and pasting from your question is working fine for the rest of us.
It looks to me that there are two problems here:
your recursive call calls sumatoria whereas your function is summation;
you check for n > 1 and n == 1 which is rather unsafe.
We can resolve the problems by subsituting sumatoria by summation, and make the guards more safe:
summation :: Integer -> Integer
summation n
| n >= 1 = n + summation (n-1)
| otherwise = 0
Now it should work. We use otherwise = 0 such that if we enter 0 or a negative number, we obtain 0.
Nevertheless we can still improve this function. First of all, we should not restrict ourselves to only Integers. We can use any kind of Numeric type a that is Orderable. So we can rewrite it to:
summation :: (Num a, Ord a) => a -> a
summation n
| n > 1 = n + summation (n-1)
| otherwise = 0
And furthermore the sum of 1..n or 0..n can be calculated by using:
n
---
\ n * (n+1)
/ i = ---------
--- 2
i=1
So we can write it as:
summation :: Integral a => a -> a
summation n = div (n * (n+1)) 2
The div :: Integral a => a -> a -> a requires a to be Integral. In case the multiplication, increment, and division are all O(1) operations, this is an O(1) function now.
Finally note that besides using recursion, you can also use functions like sum. In that case you could have used:
summation :: (Enum a, Num a) => a -> a
summation n = sum [1..n]

Translate list comprehension to Prolog

I have a list comprehension in Haskell that I want to translate to Prolog.
The point of the list comprehension is rotating a 4 by 4 grid:
rotate :: [Int] -> [Int]
rotate grid = [ grid !! (a + 4 * b) | a <- [0..3], b <- [0..3] ]
Now in Prolog, I translated it like this:
rotateGrid([T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15],
[T0,T4,T8,T12,T1,T5,T9,T13,T2,T6,T10,T14,T3,T7,T11,T15]).
Can we do better?
We can use findall/3 for list comprehensions (Cf. the SWI-Prolog Documentation). E.g.,
?- findall(X, between(1,10,X), Xs).
Xs = [1,2,3,4,5,6,7,8,9,10]
Xs is a list holding all values that can unify with X when X is a number between 1 and 10. This is roughly equivalent to the Haskell expression let Xs = [x | x <- [1..10]](1). You can read a findall/3 statement thus: "find all values of [First Argument] such that [Conditions in Second Argument] hold, and put those values in the list, [Third Argument]".
I've used findall/3 to write a predicate rotate_grid(+Grid, ?RotatedGrid). Here is a list of the approximate Haskell-Prolog equivalences I used in the predicate; each line shows the relation between the value that the Haskell expression will evaluate to and the Prolog variable with the same value:
a <- [0..3] = A in between(0, 3, A)
b <- [0..3] = B in between(0, 3, B)
(a + 4 * d) = X in X is A + 4 * D
<Grid> !! <Index> = Element in nth0(Index, Grid, Element)
Then we simply need to find all the values of Element:
rotate_grid(Grid, RotatedGrid) :-
findall( Element,
( between(0,3,A),
between(0,3,B),
Index is A + 4 * B,
nth0(Index, Grid, Element) ),
RotatedGrid
).
To verify that this produces the right transformation, I down-cased the Prolog code from the question and posed the following query:
?- rotate_grid([t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15],
[t0,t4,t8,t12,t1,t5,t9,t13,t2,t6,t10,t14,t3,t7,t11,t15]).
| true.
Footnotes:
(1): between/3 isn't actually the analogue of [m..n], since the latter returns a list of values from m to n where between(M,N,X) will instantiate X with each value between M and N (inclusive) on backtracking. To get a list of numbers in SWI-Prolog, we can use numlist(M,N,Ns). So a stricter analogue for x <- [1.10] would be the conjunction member(X, Ns), numlist(1, 10, Ns).
You want a permutation of a list. The concrete elements are not considered. Therefore, you can generalize your Haskell signature to
rotate :: [x] -> [x]
This is already a very valuable hint for Prolog: the list's elements will not be considered - elements will not even be compared. So a Prolog solution should be able to handle variables directly, like so:
?- rotateGrid(L,R).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P],
R = [_A,_E,_I,_M,_B,_F,_J,_N,_C,_G,_K,_O,_D,_H,_L,_P].
And your original definition handles this perfectly.
Your version using list comprehensions suggests itself to be realized via backtracking, certain precautions have to be taken. Using findall/3, as suggested by #aBathologist will rename variables:
?- length(L,16),rotate_grid(L,R).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P],
R = [_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,_A1,_B1,_C1,_D1,_E1,_F1].
The built-in predicate bagof/3 addresses this problem. Note that we have to declare all local, existential variables explicitly:
rotate_grid2(Grid, RotatedGrid) :-
bagof(
Element,
A^B^Index^ % declaration of existential variables
( between(0,3,A),
between(0,3,B),
Index is A + 4 * B,
nth0(Index, Grid, Element)
),
RotatedGrid).
For lists that are shorter than 16 elements, the Haskell version produces a clean error, but here we get pretty random results:
?- L=[1,2,3,4],rotate_grid(L,R).
L = [1,2,3,4], R = [1,2,3,4].
?- L=[1,2,3,4,5],rotate_grid(L,R).
L = [1,2,3,4,5], R = [1,5,2,3,4].
This is due to the unclear separation between the part that enumerates and "generates" a concrete element. The cleanest way is to add length(Grid, 16) prior to the goal bagof/3.
List comprehensions in Prolog
Currently, only B-Prolog offers a form of list comprehensions:
R#=[E: A in 0..3,B in 0..3,[E,I],(I is A+4*B,nth0(I,L,E))].
However, it does not address the second problem:
| ?- L = [1,2,3], R#=[E: A in 0..3,B in 0..3,[E,I],(I is A+4*B,nth0(I,L,E))].
L = [1,2,3]
R = [1,2,3]
yes
Use a loop predicate foreach/4
If the comprehension should retain variables, which is for example important in constraint programming, a Prolog system could offer a predicate foreach/4. This predicate is the DCG buddy of foreach/2.
Here is how variables are not retained via findall/3, the
result R contains fresh variables according to the ISO
core semantics of findall/3:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.1)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
?- functor(L,foo,5), findall(X,
(between(1,5,N), M is 6-N, arg(M,L,X)), R).
L = foo(_5140, _5142, _5144, _5146, _5148),
R = [_5210, _5204, _5198, _5192, _5186].
And here is how variables can be retained via foreach/4,
the resulting list has the same variables as the compound
we started with:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- [user].
helper(N,L) --> [X], {M is 6-N, arg(M,L,X)}.
Yes
?- functor(L,foo,5), foreach(between(1,5,N),helper(N,L),R,[]).
L = foo(_A,_G,_M,_S,_Y),
R = [_Y,_S,_M,_G,_A]
Using foreach/4 instead of bagof/3 might seem a little bit over the top. foreach/4 will probably only show its full potential when implementing Picat loops, since it can build up constraints, what bagof/3 cannot do.
foreach/4 is an implementation without the full materialization of all solution that are then backtracked. It shares with bagof/3 the reconstruct of variables, but still allows backtracking in the conjunction of the closures.

Haskell and Vim: Proper Indentation

Search for "vim haskell indent" on SO. There are lot of answers for how to configure Vim for Haskell indentation. None of them really "work". They don't provide code as is recommended by the Haskell indentation wiki page. For example, alignment of statements in a do or let block, the = and | of a data type, etc.
Does a Vim solution exist that generates code like the wiki?
This might not be the answer your are looking for, but there is a way you can follow the indentation wiki guide and be compatible with most editors.
For example, do-blocks
Instead of
myFunc x = do y <- bar
return $ x + y
You can indent it like this
myFunx x = do
y <- bar
return $ x + y
This is explicitly mentioned as an acceptable alternative in the indentation wiki.
In the same way, you can format data types
data FooBar
= Foo
| Bar
| Asdf
Guards
myFunc x
| x < 0 = 0
| otherwise = x
Where-clauses
myFunc x = x + y + c where
y = x + 5
c = x * y
And so on...
I personally started to use this kind of style because, like you said, no editor could reliable indent the code otherwise. This works better in all editors, as the indentation is always a multiple of four (or whatever else you pick for your base indentation level). As I used this style, I also started to prefer this consistent indentation level visually, so I wouldn't go back at this point even if editors got smarter.

WinHugs - how to declare a variable and a function

I've downloaded WinHugs 2 hours ago and still can't figure out how to declare simple things. I'm trying to follow the book "7 languages in 7 weeks", but stuff like let x = 10 and double x = x * 2 gives syntax errors.
I'm not 100% sure what you're trying to do that doesn't work. You can't declare bindings in a WinHugs session, you can only evaluate full expressions. So you could do things like let x = 10 in x * x + x, but you can't say let x = 10 in an interactive session. In other words, you can't make the declaration 'stick'.
To get around this, either put your declarations in a .hs file and load it in WinHugs, or use GHCi instead (this is the better option, in my opinion - WinHugs is pretty dated). You can install GHCi by downloading Haskell Platform.
in winhugs the following gives a syntax error
let double x = x * 2
but the following works:
let double x = x * 2 in double 10
however in ghc they have the interactive environment ghci where everything works
let double x = x * 2
works
double 10
works
this link explains how to work with ghci environment: https://downloads.haskell.org/~ghc/7.2.2/docs/html/users_guide/interactive-evaluation.html
One minor issue is that on windows you need the presence of cygwin - otherwise ghci as compiled for windows will not work.

Resources