Alright, so I was making some tests to get familiar with Scala, and wanted to see if I could make lists Java style rather than the fancy way you'd do it in Scala...
I know that you can do it like this: val lst = List.range(0, 100, 1) but I just wanted to see what java style would look like in scala
Alright so here's what I did:
var lst = List[Int]()
for(i <- 0 until 100) {
lst = lst :: i // here's where it complains
}
for some reason scala, or at least the scala ide for eclipse doesn't like that I append using infix notation, a-la lst :: i it wants me to do it like this: lst.::(i) otherwise it says :: isn't defined or something, it's not the first time it's happened either...
so can anyone here explain why it does that, or is it just a case of bad implementation in eclipse and thus something I have to live with
This isn't a problem with infix notation. Rather, it's because method names ending with : are applied as
a ??: b
b.??:(a)
So you simply have your arguments backwards.
lst = i :: lst
will work fine.
(Of course, you then have the issue that lists act like stacks, so you need to push the numbers on in reverse order.)
In Scala, a List is of immutable length. It can work like a LIFO (last in, first out) structure, but it cannot behave like a Java ArrayList.
You are doing this:
val lst = List[Int]()
which gives your lst a size of 0. It means you can't really do anything with it.
For a mutable collection, use ListBuffer.
Also, the :: operator is right associative, which means it will be called on the object found on the right side of the operator.
val lst = ListBuffer[Int]()
for (i <- 0 until 100) {
lst += i // will add to the tail.
}
Related
I am really new to Haskell and also really confused about how to implement for loops since I know we need to use recursion for them.
For example, I have a list [1,2,2,4,1] and want to write a function to change every 2 to a 3. How would I go about doing this? In Java, I know I would write the following
public void replace_two(List<Integer> ints) {
int i = 0;
for (int x: ints) {
if (x == 2) {
ints.set(i, 3);
}
i++;
}
System.out.println(ints);
}
but I am not sure how I could reproduce something else like this with Haskell?
There's not a single replacement for a for loop in Haskell. The replacement depends on exactly what you want to do. In this case, a map would be appropriate:
replace_two = map go
where
go 2 = 3
go x = x
And it works like this:
Prelude> replace_two [1,2,2,4,1]
[1,3,3,4,1]
Prelude>
Haskell uses a combination of different ways to 'sort of' loop over data, e.g. list.
The two important things helping this is:
Ease of declaring a function and passing it around similar to what we do to a variable in oops languages
Extensive pattern matching
So for example I declare a function in haskell to return 2 if input is 3 else return input.
return2 x = if x == 3 then 2 else x
Now we want to apply this function to every element of the list. So we will use pattern matching.
apply (x:xs) = return2 x : apply xs
apply [] = []
Here the pattern x:xs will break the list and take the first element in x while xs will have the remainder of the list. Inside the function you can see we have applied it recursively.
I have not checked the above code in IDE so it might have syntax errors, also there are other things you will want to validate (end of list, in above code the function would cause exception).
The above pattern is quite common, so there is another function in the core libraries that can do this, and is called map. So you could do:
map return2 [your list]
As I said, in haskell there are many ways to essentially loop over things, but at the base they break down to applying the function to individual items in the data structure. There are many haskell functions built on top of it like map, fold, etc.
I would suggest you use one of the several resources online to get more familiar with Haskell constructs. One that I liked and was easy to follow is Learn you a Haskell
Using map with an anonymous function:
λ> map (\x -> if x==2 then 3 else x) [1,2,2,4,1]
[1,3,3,4,1]
Another basic approach using patterns and recursion.
replace :: [Int] -> [Int]
replace [] = [] -- base case
replace (2:x) = 3:replace(x) --if 2 then replace by 3
replace (y:x) = y:replace(x) -- do nothing
Except map, maybe you can use forM from Control.Monad to mimic the for loop in other imperative languages:
import Control.Monad
arr = [1, 2, 2, 4, 1]
forM arr $ \i ->
if i == 2 then return 3 else return i
However, you need to understand what is Monad.
Is there a more efficient way to update an element in a list in Elm than maping over each element?
{ model | items = List.indexedMap (\i x -> if i == 2 then "z" else x) model.items }
Maybe Elm's compiler is sophisticated enough to optimize this so that map or indexedMap isn't unnecessarily copying over every element except 1. What about nested lists?
Clojure has assoc-in to update an element inside a nested list or record (can be combined too). Does Elm have an equivalent?
More efficient in terms of amount of code would be (this is similar to #MichaelKohl's answer):
List.take n list ++ newN :: List.drop (n+1) list
PS: if n is < 0 or n > (length of list - 1) then the new item will be added before or at the end of the list.
PPS: I seem to recall that a :: alist is slightly better performing than [a] ++ alist.
If you mean efficient in terms of performance/ number of operations:
As soon as your lists get large, it is more efficient to use an Array (or a Dict) instead of a List as your type.
But there is a trade-off:
Array and Dict are very efficient/ performant when you frequently retrieve/ update/ add items.
List is very performant when you do frequent sorting and filtering and other operations where you actually need to map over the entire set.
That is why in my code, List is what I use a lot in view code. On the data side (in my update functions) I use Dict and Array more.
Basically, an Elm list is not meant for such a use-case. Instead, consider using an Array. Array contains a set function you can use for what is conceptually an in-pace update. Here's an example:
import Html exposing (text)
import Array
type alias Model = { items : Array.Array String }
model =
{ items = Array.fromList ["a", "b", "c"]
}
main =
let
m = { model | items = Array.set 2 "z" model.items }
z = Array.get 2 m.items
output = case z of
Just n -> n
Nothing -> "Nothing"
in
text output -- The output will be "z"
If for some reason you need model.items to be a List, note that you can convert back and forth between Array and List.
I'm not overly familiar with Elm, but given that it's immutable by default, I'd assume it uses structural sharing for its underlying data structures, so your concern re memory may be unfounded.
Personally I think there's nothing wrong with your approach posted above, but if you don't like it, you can try something like this (or List.concat):
List.take n list ++ newN :: List.drop (n+1)
I'm definitely not an Elm expert, but a look at Elm's List documentation did not reveal any function to update the element at a given index in a list.
I like Michael's answer. It's quite elegant. If you prefer a less-elegant, recursive approach, you can do something like the following. (Like I said, I'm not an Elm expert, but hopefully the intention of the code is clear if its not quite right. Also, I don't do any error handling.)
updateListAt :: List a -> Int -> a -> List a
updateListAt (head :: tail) 0 x = x :: tail
updateListAt (head :: tail) i x = head :: (updateListAt tail (i - 1) x)
However, both the runtime and space complexity will be O(n) in both the average and worst cases, regardless of the method used. This is a consequence of Elm's List being a single-linked list.
Regarding assoc-in, if you look at the Clojure source, you'll see that assoc-in is just recursively defined in terms of assoc. However, I think you'd have trouble typing it for arbitrary, dynamic depth in Elm.
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 can't sleep! :)
I've written small program building double linked list in Haskell. The basic language's property to make it was lazy evaluation (see the bunch of code below). And my question is can I do the same in a pure functional language with eager evaluation or not? In any case, what properties eager functional language must have to be able to build such structure (impurity?)?
import Data.List
data DLList a = DLNull |
DLNode { prev :: DLList a
, x :: a
, next :: DLList a
}
deriving (Show)
walkDLList :: (DLList a -> DLList a) -> DLList a -> [a]
walkDLList _ DLNull = []
walkDLList f n#(DLNode _ x _) = x : walkDLList f (f n)
-- Returns first and last items.
makeDLList :: [a] -> (DLList a, DLList a)
makeDLList xs = let (first, last) = step DLNull xs in (first, last)
where
step prev [] = (DLNull, prev)
-- Here I use laziness. 'next' is not built yet, it's a thunk.
step prev (x : xs) = let this = DLNode prev x next
(next, last) = step this xs
in (this, last)
testList :: [Int] -> IO ()
testList l = let
(first, last) = makeDLList l
byNext = walkDLList next first
byPrev = walkDLList prev last
in do
putStrLn $ "Testing: " ++ show l
print byNext
print byPrev
main = do
testList []
testList [1, 2, 3, 4]
A doubly-linked list can be implemented in a purely functional way in an eager language as a zipper on a singly-linked list. See, for example, Rosetta Code > Doubly-linked list > OCaml > Functional.
As long as a language has something like closures, lambdas etc. you can always simulate lazyness. You could rewrite that code even in Java (without mutating variables etc), you just need to wrap every "lazy" operation in something like
interface Thunk<A> {
A eval();
}
Of course this would look terrible, but it is possible.
In the non-backtracking subset of Prolog, which can be seen as explicitly set-once eager pure functional language, you can build the doubly-linked lists easily. It's the referential transparency that makes it hard in Haskell, for it forbids the Prolog's explicit setting of the named, explicitly not-yet-set logical variables, and instead forces Haskell to achieve same effect in the warped way of "tying the knot". I think.
Plus, there really isn't much difference between Haskell's guarded recursion under lazy evaluation vs. Prolog's open-ended lists built in tail-recursion modulo cons fashion. IMO. Here's for instance an example of lazy lists in Prolog. The memoized shared storage is used as universal access mediator, so the results of previous calculations can be arranged to be cached.
Come to think of it, you can use C in a restrictive manner as an eager pure functional language, if you never reset any variable nor any pointer once it is set. You still have null pointers, just as Prolog has variables, so it is too, explicitly set-once. And of course you can build doubly-linked lists with it.
So the only question that remains is, do you admit such set-once languages as pure?
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.