I'd like to add an element on the "movies" list of a data type Director variable called billy.
type Name = String
type Movie = String
data Director = Director {name:: Name, movies::[Movie]}
deriving (Show)
let billy = Director "Billy J." ["Good movie 1"]
--addMovieToDirector :: Movie -> Director -> Director
addMovieToDirector m (Director n ms) = Director n (m:ms)
The problem is previous function doesn't update billy's list of movies, it creates a new Director with the desired list (the changes are not stored on billy). How can I operate on billy's list without creating another Director? I understand, that Haskell works with constants, but then should I create a different 'billy' "variable" every time I modify the list?
Thanks!
What you would like to do can be described as "in-place modification", or "using mutable data".
There are ways for Haskell to do this. Since in-place modification of anything almost always considered as a "side-effect", such things can only be done in the IO monad, or with dirty tricks like unsafePerformIO.
These are somewhat advanced topics, and at a beginner level it is arguably beneficial to think about Haskell values as being totally immutable.
So yes, you can't modify variables. Actually there are no "variables" at all.
Think about billy as a name for a value, not a variable.
All a function can do in Haskell is to take arguments, and calculate some result without any side effects.
This is probably the biggest mental barrier for people coming from imperative languages: "how should I work with data if I can't modify it"?
The answer is: you should structure your program like giant assembly line: raw materials (raw data, initial parameters, etc.) are put on the line at the beginning (the first function you call), and each workstation (function) does something useful (returns a value), consuming the result of the previous workstation. At the end, something valuable might fall off the line.
What I described is simple function composition: if you need to do c task after b, after a, on a value x, then you can write it as (c . b . a) x, or c (b (a x)) or rather c $ b $ a x.
This way, you can write programs without ever changing anything explicitly, and only describing how to create new things out of old ones.
This sounds awfully inefficient, and indeed, there are some performance implications of functional programming (let alone laziness). However the compiler is smart enough to figure out a whole lot thing about programs written in Haskell, and optimize it in certain ways.
I hope it'll all make sense soon. :)
Oh, and welcome to Haskell. ;)
You can use a State monad if you want to have a mutable state in your program, for some reason. Here's an example:
module Main where
import Control.Monad.State
type GameValue = Int
type GameState = (Bool, Int)
type Name = String
type Movie = String
data Director = Director {name:: Name, movies::[Movie]}
deriving (Show)
addMovieToDirector :: Movie -> Director -> Director
addMovieToDirector m (Director n ms) = Director n (m:ms)
handleDirector :: Name -> State Director Director
handleDirector m = do
director <- get
put (addMovieToDirector m director)
returnDirector
returnDirector = do
director <- get
return director
startState = Director "Billy J." ["Good movie 1"]
main = print $ evalState (handleDirector "Good movie 2") startState
The printed result will be
Director {name = "Billy J.", movies = ["Good movie 2","Good movie 1"]}
Here handleDirector function of type Name -> State Director Director has a mutable state inside it of type Director and a "result" value of type, again, Director. get means get the state, put is used to change it and evalstate is used to "calculate" the result, enveloped by the constructed State monad.
Related
I am trying to implement a basic function but I'm out of practice with Haskell and struggling so would really appreciate some help. My question is specifically how to select a section of a list by index. I know how to in other languages but have been struggling
[ x | x <- graph, x!! > 5 && x!! <10 ]
I have been fiddling around with basic list comprehension similar to what is above, and while I know that isn't right I was hoping a similarly simple solution would be available.
If anyone wants more information or felt like helping on the further question I have included more information below, thanks!
type Node = Int
type Branch = [Node]
type Graph= [Node]
next :: Branch -> Graph -> [Branch]
This is the individual question for the "next" function
This is the general set up information but most importantly that the graph is represented as a flattened adjacency matric
Apologies for the two pictures but it seemed the best way to convey the information.
As pointed out in the comments !! does not give you the index of a value in the way it seems you expect. It is just an infix for getting an element of a list.
There is no way to get the index of x like this in Haskell since the x object doesn't keep track of where it is.
To fix this we can make a list of objects that do keep track of where they were. This can be achieved with zip.
zip [0..] graph
This creates a list of tuples each containing their index and the value in graph.
So you can write your list comprehensions as
[ x | (index, x) <- zip [0..] graph, index > 5, index < 10 ]
Now this is not going to be terribly fast since it still needs to go through every element of the list despite the fact that we know no element after the 11th will be used. For speed we would want to use a combination of take and drop.
drop 5 (take 10 graph)
However if we wanted to do some other selections (e.g. all even indexes), we can still go back to the list comprehension.
In this case, you could drop 5 <&> take 4. As in drop 5 x & take 4. Drop skips the first few elements and take leaves out all but the first few left after the drop.
I want to create a list of "players".
The user of the program can say how many players he wants.
Amount = io:get_line("how many players? \n"),
Int = string:to_integer(Amount),
List = Lists:seq(1,Int).
But now I want to create a list of players in the form [Player1, Player2...PlayerN].
Can someone tell me how to do so?
Remember that string:to_int/1 will return a tuple, not a single value. Also keep in mind that users do some pretty wild stuff in input, so you'll want to check that. (That said... when you're just trying to get a program written for yourself to test an idea, meh, whatever.)
{PlayerCount, _} = string:to_integer(io:get_line("How many players? ")),
Pretty simple. Mess around with this a bit. Input is its own world, and its good to think through this stuff a few times in toy programs (and give yourself insane input to see how the program reacts).
From here you can do a few things. If you just want a list of tuples that indicate you have a player whose serial number is a number, that's easy with a list comprehension:
Players = [{player, Number} || Number <- lists:seq(1, PlayerCount)],
You can write that as a map as well:
Players = lists:map(fun(N) -> {player, N} end, lists:seq(1, PlayerCount)),
I find the list comprehension more readable, though. Another alternative is to write your own custom recursive function. You almost never need to do this, but if you're new to programming it is good practice, and early on its way more readable because you see exactly what is happening each iteration:
player_list(Count) -> player_list(1, Count, []).
player_list(Max, Max, Players) ->
lists:reverse(Players);
player_list(Current, Max, Players) ->
player_list(Current + 1, Max, [make_new_player(Current) | Players]).
Note that the above is equivalent to, but more naturally stated than:
player_list(Current, Max, Players) ->
Next = Current + 1,
case Next == Max of
true -> lists:reverse(Players);
false -> player_list(Next, Max, [make_new_player(Current) | Players])
end.
Matching in function heads is much more clear and readable over the course of a program than a bunch of case and if statements. Over time, though, as I mentioned above, you will eventually stop writing recursive functions yourself (for the most part) and find yourself using a lot of list operations (map, fold, filter, list comprehensions, etc.) as you gain experience.
The details of make_new_player/0,1 are entirely up to you, of course -- you didn't indicate what sort of structure you wanted for their data, but you can do whatever you want there. Here are some other ways that might play out:
[make_new_player(Z) || Z <- lists:seq(1, PlayerCount)]
or
[#player{serial = Z} || Z <- lists:seq(1, PlayerCount)]
Imagine I got the following DB:
a //primary key
b
c
d
At such the following functional dependencies are valid:
a -> bcd
b -> cd
c -> bd
Wht should I do to pass it to the third normal form?
I tried to separate as follows:
a -> b //this b is the foreing key to the b of the other tables
b -> c
b -> d
Is it correct?
You are thinking about it the wrong way. You do not play around with the dependencies (unless this is some toy HW problem that specifically tells you to); you want to split the table up so that all tables are in 3NF. In your case, this would be (I think!!):
ab
bc
cd
Where the italicized letter represents a key. Now, an example of why you do not play with dependencies:
Say this database was of people and held their SS, BDate, and Name. You could then say that SS -> BDate, Name, since it is pretty much true that your SS number is unique to you. Now, when you play around with dependencies, you play around with what the data means. It's not really up to you to say that SS number can determine your name; it simply is. Saying SS -> BDate and eliminating the Name attribute is simply false.
Similarly, with your database, although ABCD don't mean anything, their dependencies are fixed and not to be changed. So, that was my super long way of saying: split the tables, don't touch the dependencies!! =)
I am new to OCaml and am trying to learn how to update dictionary and deal with if/else conditionals.
I wrote the following code to check whether the dictionary has some key. If not, add a default value for that key. Finally print it out.
module MyUsers = Map.Make(String)
let myGraph = MyUsers.empty;;
let myGraph = MyUsers.add "test" "preset" myGraph in
try
let mapped = MyUsers.find "test" myGraph
with
Not_found -> let myGraph = MyUsers.add "test" "default" myGraph in
Printf.printf "value for the key is now %s\n" (MyUsers.find "test" myGraph)
The error message I have now is syntax error for line 6: with
What is wrong here? Also, when to use in ; or;; ?
I have done some google searches and understand that in seems to define some scope before the next ;;. But it is still very vague to me. Could you please explain it more clearly?
Your immediate problem is that, except at the top level, let must be followed by in. The expression looks like let variable = expression1 in expression2. The idea is that the given variable is bound to the value of expression1 in the body of expression2. You have a let with no in.
It's hard to answer your more general question. It's easier to work with some specific code and a specific question.
However, a semicolon ; is used to separate two values that you want to be evaluated in sequence. The first should have type unit (meaning that it doesn't have a useful value).
In my opinion, the double semicolon ;; is used only in the top-level to tell the interpreter that you're done typing and that it should evaluate what you've given it so far. Some people use ;; in actual OCaml code, but I do not.
Your code indicates strongly that you're thinking imperatively about OCaml maps. OCaml maps are immutable; that is, you can't change the value of a map. You can only produce a new map with different contents than the old one.
I have to write a program in Haskell that will solve some nondeterministic problem.
I think i understand List Monad in 75% so it is oblivious choice but...
(My problem is filling n x m board with ships and water i am given sums of rows and colums every part of ship has its value etd its not important right now).
I want to guard as early as possible to make algoritm effective the problem is that possibility of insertion of ship is dependant from what i am given / what i have inserted in previus moves lets call it board state and i have no idea how to pass it cuz i can't generate a new state from board alone)
My Algoritm is:
1. Initialize First Board
2. Generate First Row trying applying every possible insertion (i can insert sheep verticaly so i need to remember to insert other parts of sheep in lower rows)
3. Solve the problem for smaller board (ofc after generating each 2 rows i check is everything ok)
But i have no idea how can I pass new states cuz as far as i have read about State Monad it generates new state from old state alone and this is impossible for me to do i would want to generate new state while doing operations on value).
I am sorry for my hatred towards Haskell but after few years of programing in imperative languages being forced to fight with those Monads to do things which in other languages i could write almost instantly makes me mad. (well other things in Haskell are fine for me and some of them are actually quite nice).
Combine StateT with the list monad to get your desired behavior.
Here's a simple example of using the non-determinism of the list monad while still keeping a history of previous choices made:
import Control.Monad
import Control.Monad.Trans.Class
import Control.Monad.Trans.State
fill :: StateT [Int] [] [Int]
fill = do
history <- get
if (length history == 3)
then return history
else do
choice <- lift [0, 1, 2]
guard (choice `notElem` history)
put (choice:history)
fill
fill maintains a separate history for each path that it tries out. If it fills up the board it returns successfully, but if the current choice overlaps with a previous choice it abandons that solution and tries a different path.
You run it using evalStateT, supplying an initial empty history:
>>> evalStateT fill []
[[2,1,0],[1,2,0],[2,0,1],[0,2,1],[1,0,2],[0,1,2]]
It returns a list of all possible solutions. In this case, that just happens to be the list of all permutations in which we could have filled up the board.