I have a list of chars
left = ['h', 'e', 'l', 'l', 'o']
and the function
typer :: [Char] -> Char -> [Char]
typer left c = left ++ [c]
Which seems to work if I type typer left 'a' into ghci it returns "helloa" but if I then try to read left it returns "hello". Where does the "a" go? is there anyway to manipulate left using the function?
example of console output
Haskell functions are pure functions, which means they can't have side effects such as modifying variables. Your typer function computes a result based on its arguments, but it doesn't (and can't) actually modify its arguments.
As an analogy, in mathematics, if n is 4 then sqrt(n) is 2, but n is still 4 even after you've computed its square root.
If you want to capture the result of your function call so you can use it later, assign it to another variable:
right = typer left 'a'
Nope! Values in Haskell are immutable.
You have declared your left to be equal to "hello", and it will always be equal to "hello". You can hide that particular left value with some new token called left in a closer scope (such as having a function argument called left, which will make the globally defined left invisible in the function body). There is however no way to change your declared left value[1].
A new string is returned by typer, and you have to hold onto that value if you want to hold onto "helloa".
[1] In GHCi, you can hide previous definitions by re-defining them. This quietly re-purposes the existing name to point to a new value. You cannot do this in a Haskell source file.
Not usually, no. Usually, Haskell variables are not mutable. There are however libraries that contain mutable variables. For example, Data.IORef contains IORef, which is mutable. I will explain how to use them below, but as a general rule, using I would recommend against it, and instead write your code in a more functional manner.
With IORef, your function typer can be rewritten
typer :: IORef [Char] -> Char -> IO()
typer left c = writeIORef left . (++[c]) =<< readIORef left
Let us consider its different parts.
readIORef left pulls out the value "hello" from the IORef and wraps it in the IO monad.
f =<< x takes x, which is wrapped in a monad, unwraps it and passes it as an argument to f, but only if we promise that f returns a value wrapped in the same monad. Here, x is "hello" wrapped in IO and f is writeIORef left . (++[c]).
. combines the functions writeIORef left and (++[c]) into one, so that (++[c]) is applied before writeIORef left.
(++[c]) appends the character c.
writeIORef left returns an empty action wrapped in IO (IO()), but it has the side effect that the value of the IORef left is modified. Since it returns a value wrapped in IO, the promise we made to =<< is fulfilled.
With the above function, the code
main :: IO()
main = do x <- newIORef "hello"
typer x 'a'
readIORef x >>= print
should yield the desired effect.
Related
Implement the function ticktack which has 2 arguments. First argument is a tuple of natural numbers and defines the number of rows and columns of a play field. Second list contains a record of a match of ticktacktoe game given by coordinates on which played in turns player 'x' and player 'o'. Print actual state of the game in the way where play-field will be bordered by characters '-' and '|', empty squares ' ' and characters 'x' and 'o' will be on squares where the players have played.
ticktack::(Int,Int) -> [(Int,Int)] -> Result
I already tried something like this:
type Result = [String]
pp :: Result -> IO ()
pp x = putStr (concat (map (++"\n") x))
ticktack::(Int,Int) -> [(Int,Int)] -> Result
ticktack (0,0) (x:xs) = []
ticktack (a,b) [] = []
ticktack (a,b) (x:xs) =[ [if a == fst x && b == snd x then 'x' else ' ' | b <- [1..b]]| a <- [1..a]] ++ ticktack (a,b) xs
But it returns me only N [Strings] with 1 result, so i need these results merge into one [String].
As #luqui says in a comment to the question:
You could either merge the outputs ... or you could search the history once for each space in
the board. ...
The former solution is described in a nearby question. The "chess" problem having been
solved there is only superficially distinct from your "noughts & crosses" problem, so it should
not be too hard to adapt the solution. However:
In that case, the board size is fixed and small, so we were not worried about the inefficiency
of merging the boards pairwise.
In this case, the board size is variable, so a solution by the latter method may be worth a try.
To make the algorithm even more efficient, instead of scrolling across the board and searching for
matching moves at every cell, we will scroll across the moves and assign values to a board
represented as a mutable array. Mutable arrays may be considered an "advanced technique" in
functional programming, so it could also be a good exercise for an intermediate Haskeller. I only
used them once or twice before, so let us see if I can figure this out!
How is this going to work?
At the heart of the program will be a rectangular array of bytes. An array goes in two flavours:
mutable and "frozen". While a frozen array cannot be changed, It is a rule that a mutable array
may only exist in a monadic context, so we can only freely pass around an array when it is frozen.
If this seems to be overcomplicated, I can only ask the reader to believe that the additional
safety guarantees are worth this complication.
Anyway, here are the types:
type Position = (Int, Int)
type Field s = STUArray s Position Char
type FrozenField = UArray Position Char
We will create a function that "applies" a list of moves to an array, thawing and freezing it as
needed.
type Move = (Char, Position)
applyMoves :: FrozenField -> [Move] -> FrozenField
(The idea of Move is that it is sufficient to put a mark on the board, without needing to know
whose turn it is.)
Applied to an empty field of the appropriate size, this function will solve our problem — we shall
only need to adjust the format of the input and the output.
empty :: Position -> FrozenField
positionsToMoves :: [Position] -> [Move]
arrayToLists :: FrozenField -> [[Char]]
Our final program will then look like this:
tictac :: Position -> [Position] -> IO ()
tictac corner = pp . arrayToLists . applyMoves (empty corner) . positionsToMoves
I hope it looks sensible? Even though we have not yet written any tangible code.
Can we write the code?
Yes.
First, we will need some imports. No one likes imports, but, for some reason, it is not yet
automated. So, here:
import Data.Foldable (traverse_)
import Data.Array.Unboxed
import Data.Array.ST
import GHC.ST (ST)
The simplest thing one can do with arrays is to create an empty one. Let us give it a try:
empty :: Position -> FrozenField
empty corner = runSTUArray (newArray ((1, 1), corner) ' ')
The idea is that newArray claims a region in memory and fills it with spaces, and runSTUArray
freezes it so that it can be safely transported to another part of a program. We could instead
"inline" the creation of the array and win some speed, but we only need to do it once, and I
wanted to keep it composable — I think the program will be simpler this way.
Another easy thing to do is to write the "glue" code that adjusts the input and output format:
positionsToMoves :: [Position] -> [Move]
positionsToMoves = zip (cycle ['x', 'o'])
arrayToLists :: FrozenField -> [[Char]]
arrayToLists u =
let ((minHeight, minWidth), (maxHeight, maxWidth)) = bounds u
in [ [ u ! (row, column) | column <- [minWidth.. maxWidth] ] | row <- [minHeight.. maxHeight] ]
Nothing unusual here, run-of-the-mill list processing.
Finally, the hard part — the code that applies any number of moves to a given frozen array:
applyMoves :: FrozenField -> [Move] -> FrozenField
applyMoves start xs = runSTUArray (foldST applyMove (thaw start) xs)
where
foldST :: (a -> b -> ST s ()) -> ST s a -> [b] -> ST s a
foldST f start' moves = do
u <- start'
traverse_ (f u) moves
return u
applyMove :: Field s -> Move -> ST s ()
applyMove u (x, i) = writeArray u i x
The pattern is the same as in the function empty: modify an array, then freeze it — and all the
modifications have to happen in an ST monad, for safety. foldST contains all the
"imperative" "inner loop" of our program.
(P.S.) How does this actually work?
Let us unwrap the UArray and STUArray types first. What are they and what is the difference?
UArray means "unboxed array", which is to say an array of values, as opposed to an array of
pointers. The value in our case is actually a Unicode character, not a C "byte" char, so it is not a byte, but a variable
size entity. When it is stored in unboxed form, it is converted to an Int32 and back invisibly
to us. An Int32 is of course way too much for our humble purpose of storing 3 different values,
so there is space for improvement here. To find out more about unboxed values, I invite you to
check the article that introduced them back in 1991, "Unboxed Values as First Class Citizens in
a Non-Strict Functional Language".
That the values are unboxed does not mean that you can change them though. A pure value in Haskell
is always immutable. So, were you to change a single value in an array, the whole array would be
copied — expensive! This is where STUArray comes in. ST stands for State Thread, and what
STUArray is is an "unfrozen" array, where you can overwrite individual values without copying
the whole thing. To ensure safety, it can only live in a monad, in this case the ST monad.
(Notice how an STUArray value never appears outside of an ST s wrap.) You can imagine an
ST computation as a small imperative process with its own memory, separate from the outside
world. The story goes that they invented ST first, and then figured out they can get IO from
it, so IO is actually ST in disguise. For more details on how ST works, check out the
original article from 1994: "Lazy Functional State Threads".
Let us now take a more careful look at foldST. What we see is that functionally, it does not
make sense. First we bind the value of start' to u, and then we return u — the same
variable. From the functional point of view, this is the same as writing:
u <- start'
return u
— Which would be equivalent to u by monad laws. The trick is in what happens inbetween:
traverse_ (f u) moves
Let us check the type.
λ :type traverse_
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
So, some function is being called, with u as argument, but the result is the useless () type.
In a functional setting, this line would mean nothing. But in a monad, bound values may appear
to change. f is a function that can change the state of a monad, and so can change the value of
the bound names when they are returned. The analogous code in C would go somewhat like this:
char* foldST(void f(char*, Move), int n_start, char start[], int n_moves, Move moves[])
{
// u <- start
char* u = malloc(sizeof(char) * n_start);
memcpy(u, start, sizeof(char) * n_start);
// traverse_ (f u) moves
for (int i = 0; i < n_moves; i++)
{
f(u, moves[i]);
}
// return u
return u;
}
In Haskell, the pointer arithmetic is abstracted away, but essentially traverse_ in ST works
like this. I am not really familiar with C nor with the inner workings of the ST abstraction, so
this is merely an analogy, not an attempt at a precise rendition. Nevertheless I hope it helps the reader to observe the similarity between ST and ordinary imperative C code.
Mission accomplished!
It runs reasonably fast. Takes only a moment to draw a million-step match on a million-sized
board. I hope it is also explained clearly enough. Do not hesitate to comment if something is amiss or unclear.
I have an exercise that asks for a function that converts all characters of a string to uppercase using
System.Char.ToUpper
So first I changed the string to a char array and changed the array into a list of chars
let x = s.ToCharArray()
List.ofArray x
Next, I thought I would use List.iter to iterate through my list and use the System.Char.ToUpper function on each character.
List.iter (fun z -> (System.Char.ToUpper(z)))
This is not working however. I get an error 'The expression was supposed to have unit but here has char.' What am I doing wrong? Is it a flaw in logic or syntax?
This needs some unpacking.
First, your core mistake: System.Char.ToUpper is a function. It takes a char and returns another char. It doesn't somehow "update" its argument to a new value.
let x = 'a'
let y = System.Char.ToUpper x // y = 'A', x = 'a'.
In the above code, I give name y to the result of the function. The value of y is 'A', but the value of x is still 'a'. After calling the function, x hasn't changed.
From this mistake, all the rest follows.
Second, List.iter is a function that, for every element of a list, makes something "happen". It doesn't replace each element of a list with something new, nor does it create a new list. It just makes something happen for every element. The simplest example of such "something" is printing out to console:
List.iter (fun x -> printfn "%i" x) [1; 2; 3] // Prints "1", then "2", then "3"
Notice that this function takes two arguments: the function that represents the something that need to happen, and the list from which to take the elements. In your question, you seem to be missing the second argument. How would List.iter know which list to use?
The first argument of List.iter needs to be a function that returns unit. This is a special type in F# that basically means "no value". When a function returns no value, it means that the only reason for calling it was to make something external happen (known in functional programming as "side-effect"). This is why List.iter requires the function to return unit - it's extra protection from accidentally supplying wrong function, just as you did, actually: the function you provided returns char. This is why you receive the error that you receive.
Third, just like with ToUpper, calling List.ofArray doesn't somehow "update" x to be a list. Instead, it returns a list. If you don't give that returned list a name, it will just be lost. Which means that the way you're calling List.ofArray is futile.
What you actually need is to (1) take the sequence of characters in your string, then (2) convert it to a new sequence where each character is upper case, then (3) glue those characters back together to get a new string.
Step (1) is a no-op, because .NET strings are already sequences of chars (i.e. they implement IEnumerable<char>). Step (2) is accomplished via a common operation called Seq.map. It's an operation that converts a sequence to a new sequence by applying given function to every element. The "given function" in this case will be System.Char.ToUpper. Step (3) can be accomplished via String.concat, but you'd need to convert each char to a string first, because String.concat takes a sequence of strings, not chars.
let chars = s
let upperChars = Seq.map System.Char.ToUpper chars
let strChars = Seq.map string upperChars
let result = String.concat "" strChars
Or this can be done in a shorter way, without giving each step's result a separate name, but by piping each result straight into the next operation:
let result =
s
|> Seq.map System.Char.ToUpper
|> Seq.map string
|> String.concat ""
And finally, there is actually a much shorter way to do it, but it's so ridiculously obvious, it feels like cheating.
The thing is, because strings are sequences, it kinda makes sense for them to have all the sequence operations. And guess what? They do! Specifically, there is a function String.map, which does the same thing as Seq.map, but for strings:
let result = String.map System.Char.ToUpper s
I have a list of lists like so:
[["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
I've done a little research and have found out how to access individual elements using the !! operator. But when it comes to searching for a certain element 'M' I'm not sure how to go about that. My friend said I need to use something like (x:xs):xss on a list, but when I try this in the WinGHCi haskell program I get this.
Prelude> let list = [["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
Prelude> head(x:xs):xss
<interactive>:192:2: Not in scope: `x'
<interactive>:192:4: Not in scope: `xs'
<interactive>:192:8: Not in scope: `xss'
I understand that I declare the name as list and not x:xs but even when I declare it as x:xs I still get the errors. I'm probably still a little new to haskell to really understand what to do so I may be going about this way wrong.
I've looked here Replace individual list elements in Haskell? because eventually I want to replace the M with something different but I'm not completely sure how I would implement that.
Any help/guidance is appreciated, thanks!
First let's see how to replace a W with M
charWM :: Char -> Char
charWM 'W' = 'M' -- If you see W, put M.
charWM x = x -- If you see anything else, put it back as is.
You can rewrite that function how you like by adding other letter transformations.
Now let's make that work over a list. There's a great function map :: (a ->b) -> [a] -> [b] that lets you apply a function on every element on a list.
stringWM :: String -> String
stringWM xs = map charWM xs -- do charWM to everything in xs.
For example stringWM "QWERTY WILL WIN" = "QMERTY MILL MIN"
Next we can do that to a list of lists:
lolWM :: [String] -> [String]
lolWM xss = map stringWM xss
(String is a type synonym for [Char].)
Let's test that out in ghci:
*Main> list'
["BBBBBBBB","BWFFFPFGB","BWFFFPFGB","BWFFMPFGB","BWFFFPF_B","BWFFFPF6B","BBBBBBB"]
*Main> lolWM list'
["BBBBBBBB","BMFFFPFGB","BMFFFPFGB","BMFFMPFGB","BMFFFPF_B","BMFFFPF6B","BBBBBBB"]
All good.
Your example wasn't exactly list', it was [list'] which has 1 element, so to work on that we'd need to map lolWM. Often we wouldn't bother writing stringWM or lolWM and go directly to lists of lists of lists, if that's what we needed:
lololWM = (map.map.map) charWM
map.map.map means map the map of the map. You can allow that to blow your mind a little, or you can just say list of list of list of Char, so map map map - one map per list level.
In the future, maybe you'll want to replace W with Strings instead of characters.
rewriteChar :: Char -> String
rewriteChar 'W' = "--^--"
rewriteChar x = [x] -- put x in a list to make it a string
This time, map isn't enough: map rewriteChar "QWERTY WILL WIN" gives
["Q","--^--","E","R","T","Y"," ","--^--","I","L","L"," ","--^--","I","N"]
We could use concat on that to flatten it into a single list, but it's more fun to do
rewriteString = concatMap rewriteChar
So now rewriteString "QWERTY WILL WIN" give us "Q--^--ERTY --^--ILL --^--IN".
For more mindblowing things to try, there's "QWERTY WILL WIN" >>= rewriteChar and "Hello Mum" >>= \x -> [x,x,x]
First of all, virtually all "variables" in Haskell are immutable, so there's no "changing a list", there are modified copies.
Second, you need to find an element by some criteria. To do that, you need to traverse a list. - This can be done using recursion. Filtering can be done using a function passed as an argument of your traversing function (this function must take an element and return a boolean value).
Try to put the above together and make your own function. Start with a type signature, it shows what you want to do: to take a list of Char (it's better to generalize to a generic type) and a function which possibly changes an element and return a modified list:
replaceFunc :: (Char -> Char) -> String -> String
Also, read http://www.haskell.org/haskellwiki/How_to_work_on_lists , there's a hint there how to apply some function to specific elements only.
I am given an array of Char and have to translate it to Moves (as shown below)
data Move = N | S | W | E | X
newtype Moves = Moves [Move]
createMoves:: [Char]-> Moves
createMoves (x:xs) = if xs==[] then Moves [createMove(x)]
else Moves [createMove (x)]
createMove:: Char-> Move
createMove (x) = if x=='N' then N
else if x=='S' then S
else if x=='W' then W
else if x=='E' then
else X
However, I am only succeeding in getting the first item of the list. I have tried a number of ways to make createMoves recursive but I can't get it right. Could you please guide me?
Branches of your if statement are the same, so it does nothing.
When programming recursive functions, there are two cases.
The basic one, you should declare createMoves [] = [].
The recursive is a little more complicated; basically, for each x you create a move that is the first element appended to a list built using a recursive call on xs.
A simpler way is to use the map function. You can also look at its implementation.
By the way, for createMove you could use pattern matching instead of many ifs.
Your problem seems to be centering on combining the result of the recursive call on xs with the result of createMove x. So, let's just introduce a helper function which is going to take care of that!
createMoves:: [Char]-> Moves
createMoves (x:xs) = if xs==[] then Moves [createMove x]
else createHelper (createMove x) (createMoves xs)
Now, what should the type of createHelper be? Its first argument is a Move and the second is a Moves, and it should put the first argument in front of the list of Moves contained in the second, and 'repack' it in a value of type Moves. To get at the list of Moves you need to use pattern matching, like so:
createHelper :: Move -> Moves -> Moves
createHelper m (Moves ms) = Moves (m:ms)
That should do the trick, but all this matching on the Moves constructor and then reapplying it is a bit silly, and potentially inefficient. A better approach is to convert the [Char] one-by-one to [Move] and only at the end tacking the Moves constructor on. That leads to something like (still in keeping with your original idea):
createMoves :: [Char] -> Moves
createMoves cs = Moves (createMoveList cs)
createMoveList :: [Char] -> [Move]
createMoveList (x:xs) = if xs == [] then [] else createMove x : createMoveList xs
createMoveList is a pattern that comes up very often in Haskell, namely that of applying a function (in this case, createMove) to each element in a list. This is the essence of the map function (which I'm sure you'll get to very soon in your lessons, if you haven't already!).
If you use that, you can also get rid of the problem that createMoves fails when given an empty list. So the solution I would go with is:
createMoves :: [Char] -> Moves
createMoves cs = Moves (map createMove cs)
or
createMoves = Moves . map createMove
but that's another story!
Your createMoves function only operates on one element of the list it's given.
Try using the map function. On other words, start your function with:
createMoves list = Moves (map
[...]
You may wish to use Guards (i.e. |) instead of if, then and else.
First, you should remove the newtype statement; if you want the list to print, just have the Move type derive Show.
Next, you can remove the explicit recursion in the createMoves function by using map. For future reference, you can look for functions by name and type signature on Hoogle.
Finally, you can use pattern matching to eliminate all the equality tests against constants. An irrelevant example using the Move type is
isN :: Move -> Bool
isN N = True
isN _ = False
Note that the _ character means "ignore this value". If you haven't covered pattern matching yet, then guards might still be better than nested ifs.
I need a function that recursively returns (not prints) all values in a list with each iteration. However, every time I try programming this my function returns a list instead.
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
I need to use each element each time it is returned in another function that I wrote, so I need these elements one at a time, but I can't figure this part out. Any help would be appreciated.
Your function is equivalent to :
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
This happens because a ; b evaluates a (and discards the result) and then evaluates and returns b. Obviously, this is in turn equivalent to:
let elements (list : 'a list) = []
This is not a very useful function.
Before you try solving this, however, please understand that Objective Caml functions can only return one value. Returning more than one value is impossible.
There are ways to work around this limitation. One solution is to pack all the values you wish to return into a single value: a tuple or a list, usually. So, if you need to return an arbitrary number of elements, you would pack them together into a list and have the calling code process that list:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
Another less frequent solution is to provide a function and call it on every result:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
This is less flexible, but arguably faster, than returning a list : lists can be filtered, sorted, stored...
Your question is kind of confusing - you want a function that returns all the values in a list. Well the easiest way of returning a variable number of values is using a list! Are you perhaps trying to emulate Python generators? OCaml doesn't have anything similar to yield, but instead usually accomplishes the same by "passing" a function to the value (using iter, fold or map).
What you have currently written is equivalent to this in Python:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
If you are trying to do this:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
The equivalent in OCaml would be like this:
List.iter dosomething [1;2;3;4;5]
If you are trying to determine if list a is a subset of list b (as I've gathered from your comments), then you can take advantage of List.mem and List.for_all:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b defines a function that returns true if the value x is equal to any element in (is a member of) b. List.for_all takes a function that returns a bool (in our case, the membership function we just defined) and a list. It applies that function to each element in the list. If that function returns true for every value in the list, then for_all returns true.
So what we have done is: for all elements in a, check if they are a member of b. If you are interested in how to write these functions yourself, then I suggest reading the source of list.ml, which (assuming *nix) is probably located in /usr/local/lib/ocaml or /usr/lib/ocaml.