Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Today I have a new problem with another code in Haskell: I get the following error "parse error on input `<-'". Would someone explain to me what is wrong with the code and how to make it right? Thanks!
f :: (Int,Int) -> (Int,Int) -> Int -> Int -> [[Int]]
f (h, w) (a, b) k l = let x <- [1..w]
y <- [1..h]
zahl1 <- [1..k]
zahl2 <- [1..l]
in [if ((y, x) == (a, b)) then zahl1 else zahl2] ```
The left arrow (<-) is used to assign values inside do notation, like this:
main = do
line <- getLine
print line
The equals sign is used to assign values as part of a let ... in ... expression, like this:
main =
let line = "hello"
in print line
So mechanically you might think to replace <- with =, but that wouldn't work for your case. It looks like you're trying to create a list using a list comprehension, but instead you're creating a list with only one value in it. I think this may be what you're trying to do:
f :: ( Int, Int ) -> ( Int, Int ) -> Int -> Int -> [ [ Int ] ]
f ( h, w ) ( a, b ) k l =
let
zahl1 = [ 1 .. k ]
zahl2 = [ 1 .. l ]
in
[ if ( y, x ) == ( a, b ) then zahl1 else zahl2
| x <- [ 1 .. w ]
, y <- [ 1 .. h ]
]
I wouldn't necessarily recommend this, but as a bit of trivia you can write list comprehensions using do notation:
f ( h, w ) ( a, b ) k l = do
x <- [ 1 .. w ]
y <- [ 1 .. h ]
if ( y, x ) == ( a, b )
then [ 1 .. k ]
else [ 1 .. l ]
Related
I have problems to understand the following piece of code:
treePositions :: Tree a -> [[Int]]
treePositions (Node _ ts) =
[] : [ (i : is ) | i <- [0..(length ts - 1)],
is <- treePositions (index ts i) ]
This function would calculate any valid paths to a position in the given tree, where for every node the edges are marked with 0..lastOutgoingEdge.
If I understood it right the index function would return the node at Index i in the node list of the tree.
index :: [a] -> Int -> a
index :: [a] -> Int -> a
index [] i = error "invalid index"
index (x:xs) 0 = x
index (x:xs) i = ith xs (i-1)
Now for given trees:
t1 = Node "a" [
Node "b" [
Node "c"[],
Node "d"[]
]
]
t2 = Node "z" []
the function would return:
treePositions t1 == [ [], [0], [0,0], [0,1] ]
treePositions t2 == [ [] ]
What I don't understand is this part:
[] : [ (i : is ) | i <- [0..(length ts - 1)],is <- treePositions (index ts i) ]
My thoughts:
If I have x|x <- [0..10], x < 2. This would translate in "take every x in [0..10] for which x < 2 applies. So if I would take every i in [0..(length ts - 1)], how would this then return lists for a condition?
In your case, the part after the comma is not a condition, but a second generator. Simplified, the notation looks like this:
> [ (a, b) | a <- [1..3], b <- [1..2] ]
> [(1,1),(1,2),(2,1),(2,2),(3,1),(3,2)]
The example compherension above means the following:
go through list [1..3], and for every element of it,
go through list [1..2], and for every element of it,
produce a tuple
Further, a generator can depend on elements of previous generators, e.g.:
> [ (a, b) | a <- [1..3], b <- [1..a] ]
> [(1,1),(2,1),(2,2),(3,1),(3,2),(3,3)]
So in your case:
[ (i : is ) | i <- [0..(length ts - 1)],is <- treePositions (index ts i) ]
the logic is this:
for every i in 0..(length ts - 1),
go through every is in treePositions (index ts i),
and produce i : is as result
I've created the following data types.
{- Data declaration predefined in Haskell -}
data Maybe_ a = Nothing_ | Just_ a deriving( Show )
{- Array declaration -}
data Array_ a = A [ ( Int, Maybe_ a ) ] deriving( Show )
Now, I'd like to create an update function that - given an index, an Array_ and a new value - update the value of the array at the given index.
Here's the signature of the function ...
update :: ( Int, Array_ a, a ) -> Array_ a
... and here's the complete function
update :: ( Int, Array_ a, a ) -> Array_ a
update( i, A[], new_value ) = error( ( show i ) ++ " is not an index" )
update( i, A( ( j, Just_ x ):l ), new_value )
| i == j = A( ( j, Just_ new_value ):l )
| i /= j = update ( i, A l, new_value )
The issue occurs at the last line of the function. It's a recursive call to the end of the list, but it doesn't keep the previously consider elements of the array.
I was thinking of using either the ++ operator or the : one, but both of the time I get an error.
... i /= j = ( j, Just_ x ):update ( i, A l, new_value )
... i /= j = A[( j, Just_ x )] ++ update ( i, A l, new_value )
How can I handle this differently?
First of all it is a bit un-Haskell to work with tuples, usually you define separate parameters, like:
update :: Int -> Array_ a -> a -> Array_ a
So that you can easily work with an update 5 function where you will later provide additional arguments.
Nevertheless the problem is that in your last branch:
| i /= j = update i (A l) new_value
you thus perform a recursive call, but the result of that recursive call will be the final result. In order to solve this issue, you simply prepend the item that you inspected, and did not match the index. Since you do this for all index failure, all indices that do not match will be in the final result, so:
| i /= j = (j, Just_ x) : update i (A l) new_value.
So now we obtain:
update :: Int -> Array_ a -> a -> Array_ a
update i (A []) new_value = error( ( show i ) ++ " is not an index" )
update i (A ((j, Just_ x):l)) new_value
| i == j = A ((j, Just_ new_value):l)
| i /= j = let A t = update i (A l) new_value in A ((j, Just_ x):t)
That being said there are still some things we can do to improve our function:
variables we do not take into account are usually written with a wildcard,
we can use an alias # to prevent us from repacking the head of the list.
the compiler will probably error since you use == and /=. It is better to use otherwise (an alias of True in the last branch (this is more or less equivalent with else in Java).
there are some additional beautifications you can obtain with hlint.
If we take the above comments into account, an - in my opinion - more elegant function would be:
update :: Int -> Array_ a -> a -> Array_ a
update i (A []) _ = error $ show i ++ " is not an index"
update i (A (h#(j,Just_):l)) new_value
| i == j = A ((j, Just_ new_value):l)
| otherwise = let A t = update i (A l) new_value in A (h:t)
Finally there is still a case unresolved: what to do if there are Nothing_s in your list. If you don't care whether the value is a Just_ x or a Nothing_, you can rewrite it like:
update :: Int -> Array_ a -> a -> Array_ a
update i (A []) _ = error $ show i ++ " is not an index"
update i (A (h#(j,_):l)) new_value
| i == j = A ((j, Just_ new_value):l)
| otherwise = let A t = update i (A l) new_value in A (h:t)
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I want to create the function allSum which should be declared in this way
allSum:: (Int->Int)->(Int->Int)
this is what it should do:
(allSum f) n = f (0 )+ f (1)+ f (2) +…+ f (n)
this is my attempt:
sum1 = foldr (+)0
allSum:: (int->int) -> (int->int)
allSum f = \n -> ( sum1 [ f(x)| x <-[0..n]])
however, it doesn't work and I am not sure why.
If you change int to Int it will work just fine:
sum1 = foldr (+) 0
allSum :: (Int -> Int) -> (Int -> Int)
allSum f = \n -> sum1 [ f(x) | x <- [0..n] ]
Live demo
On a side note you can write your allSum function as:
allSum :: (Int -> Int) -> (Int -> Int)
allSum f = \n -> sum . fmap f $ [0..n]
I've been playing with Haskell and writing some code to parse DICOM medical images. The code is here. I wanted to create a function that will take in a ByteString and return a name. So a certain ByteString (actually two Int64s taken from a ByteString) would return PatientName or StudyDate for example. There are thousands of these and they are all contained within an XML file. So to create the function I parse the XML file and generate the desired function and output to a file using
writeTagNameFromElemGroup :: FilePath -> [(String,String,String,String)] -> IO()
writeTagNameFromElemGroup fp tups = init >> Prelude.appendFile fp ( Prelude.drop 0 tags )
where init = Prelude.appendFile fp "\ntagNameFromElem :: Element -> Group -> String\ntagNameFromElem e g\n"
tags = LS.concat $ Prelude.map (\tup -> " | " ++ (writeTup tup) ++ "\n") filTups
hexInt x = show . readHex $ x
filTups = LS.filter (\(w,x,y,z) -> Prelude.length w == 4 && Prelude.length x ==4 ) tups
This creates the desired function in Tags.hs
tagNameFromElem :: Int64 -> Int64 -> String
tagNameFromElem e g
| e == 8 && g == 1 = "LengthToEnd"
| e == 8 && g == 5 = "SpecificCharacterSet"
| e == 8 && g == 6 = "LanguageCodeSequence"
| e == 8 && g == 8 = "ImageType"
| e == 8 && g == 16 = "RecognitionCode"
| e == 8 && g == 18 = "InstanceCreationDate"
| e == 8 && g == 19 = "InstanceCreationTime"
| e == 8 && g == 20 = "InstanceCreatorUID"
| e == 8 && g == 22 = "SOPClassUID"
| e == 8 && g == 24 = "SOPInstanceUID"
| e == 8 && g == 26 = "RelatedGeneralSOPClassUID"
| e == 8 && g == 27 = "OriginalSpecializedSOPClassUID"
..... > 2000 more
Every so often there is a special case like
| e == 1000 && mod (g -5) 10 == 0 = "ShiftTableTriplet"
which put me off just using a map.
Now this approach works but it takes a very long time to load (Over a minute) the whole which makes me think that I'm not doing this how it should be done. To reproduce I suggest cloning the repo and loading the Tags.hs.
A SSCE
writeFunc :: (Num x, Show x) => FilePath -> [x] -> IO()
writeFunc fp xs = init >> Prelude.appendFile fp ( maps ) >> Prelude.appendFile fp "| otherwise = 0 "
where init = Prelude.appendFile fp "mapVal :: Int -> Int \nmapVal x\n "
maps = concat $ Prelude.map (\x -> "| x == " ++ show x ++ " = " ++ show (x +1 ) ++ "\n ") xs
Use a long list ~ few thousand values and try to import the resulting file
This answer is based on what bheklilr suggested in the question's comments. Code generation is up to you.
I reviewed your code and found that there are only two values in which e imposes special conditions on g: e == 28 and e == 1000. So, it'd be better to handle those in separate functions. Choose better names than the following ones, please.
e28 :: Map Int64 String
e28 = fromList [ (0, "CodeLabel"), (2, "NumberOfTables"), ... ]
e1000 :: Map Int64 String
e1000 :: fromList [ (0, "EscapeTriplet"), (1, "RunLengthTriplet"), ... ]
The keys of the previous maps are taken from your special-case predicate: mod (g - key) 10 == 0.
The case where e == 1010 is also special, since it doesn't depend on g. It's always "ZonalMap", so it'll be dealt with later.
Now, just create the rest of maps using g as key.
e40 :: Map Int64 String
e40 = fromList [ (2, "SamplesPerPixel"), (3, "SamplesPerPixelUsed"), ... ]
e84 :: Map Int64 String
e84 = fromList [ ... ]
...
Create a map from regular es (i.e. not the 28, 1000 or 1010 ones) to their corresponding map:
regularE :: Map Int64 (Map Int64 String)
regularE e = fromList [ (40, e40), (84, e84), ... ]
To sum it all up:
import Control.Monad
tagNameFromElem :: Int64 -> Int64 -> Maybe String
tagNameFromElem 28 g = lookup e28 (mod g 10)
tagNameFromElem 1000 g = lookup e1000 (mod g 10)
tagNameFromElem 1010 _ = Just "ZonalMap"
tagNameFromElem e g = lookup regularE e >>= (`lookup` g)
The lookup function is from Data.Map, just in case qualification is required. Using Maybe handles the case where e or g do not map to a valid tag name, instead of a hardcoded "Not Found" string.
Note that I haven't tested this code; I'm not at home right now.
If you want, try IntMap instead of Map. You'll need to work with regular Ints in this case, but it may be good for this project.
I've written an answer to the bounded knapsack problem with one of each item in Scala, and tried transposing it to Haskell with the following result:
knapsack :: [ ( Int, Int ) ] -> [ ( Int, Int ) ] -> Int -> [ ( Int, Int ) ]
knapsack xs [] _ = xs
knapsack xs ys max =
foldr (maxOf) [ ] [ knapsack ( y : xs ) ( filter (y /=) ys ) max | y <- ys
, weightOf( y : xs ) <= max ]
maxOf :: [ ( Int, Int ) ] -> [ ( Int, Int ) ] -> [ ( Int, Int ) ]
maxOf a b = if valueOf a > valueOf b then a else b
valueOf :: [ ( Int, Int ) ] -> Int
valueOf [ ] = 0
valueOf ( x : xs ) = fst x + valueOf xs
weightOf :: [ ( Int, Int ) ] -> Int
weightOf [ ] = 0
weightOf ( x : xs ) = snd x + weightOf xs
I'm not looking for tips on how to clean up the code, just to get it working. To my knowledge it should be doing the following:
For each tuple option (in ys)
if the weight of the current tuple (y) and the running total (xs) combined is less than the capacity
get the optimal knapsack that contains the current tuple and the current total (xs), using the available tuples (in ys) less the current tuple
Finally, get the most valuable of these results and return it
*Edit: * Sorry, forgot to say what's wrong... So it compiles alright, but it gives the wrong answer. For the following inputs, what I expect and what it produces:
knapsack [] [(1,1),(2,2)] 5
Expect: [(1,1),(2,2)]
Produces: [(1,1),(2,2)]
knapsack [] [(1,1),(2,2),(3,3)] 5
Expect: [(2,2),(3,3)]
Produces: []
knapsack [] [(2,1),(3,2),(4,3),(6,4)] 5
Expect: [(2,1),(6,4)]
Produces: []
So I was wondering what could be the cause of the discrepancy?
The solution, thanks to sepp2k:
ks = knapsack []
knapsack :: [ ( Int, Int ) ] -> [ ( Int, Int ) ] -> Int -> [ ( Int, Int ) ]
knapsack xs [] _ = xs
knapsack xs ys max =
foldr (maxOf) [ ] ( xs : [ knapsack ( y : xs ) ( ys #- y ) max
| y <- ys, weightOf( y : xs ) <= max ] )
(#-) :: [ ( Int, Int ) ] -> ( Int, Int ) -> [ ( Int, Int ) ]
[ ] #- _ = [ ]
( x : xs ) #- y = if x == y then xs else x : ( xs #- y )
maxOf :: [ ( Int, Int ) ] -> [ ( Int, Int ) ] -> [ ( Int, Int ) ]
maxOf a b = if valueOf a > valueOf b then a else b
valueOf :: [ ( Int, Int ) ] -> Int
valueOf [ ] = 0
valueOf ( x : xs ) = fst x + valueOf xs
weightOf :: [ ( Int, Int ) ] -> Int
weightOf [ ] = 0
weightOf ( x : xs ) = snd x + weightOf xs
Which returns the expected results, above.
Your first case fires when ys contains. so for knapsack [foo,bar] [] 42, you get back [foo, bar], which is what you want. However it does not fire when ys contains nothing except elements that would put you over the max weight, i.e. knapsack [(x, 20), (y,20)] [(bla, 5)] will return [] and thus discard the previous result. Since this is not what you want you should adjust your cases so that the second case only fires if there's at least one element in ys that's below the max weight.
One way to do that would be to throw out any elements that put you over the max weight when recursing, so that that scenario simply can't happen.
Another way would be to switch the order of the cases and add a guard to the first case that says that ys must contain at least one element that does not put you over the total weight (and adjust the other case to not require ys to be empty).
PS: Another, unrelated problem with your code is that it ignores duplicates. I.e. if you use it on the list [(2,2), (2,2)] it will act as if the list was just [(2,2)] because filter (y /=) ys will throw out all occurrences of y, not just one.
Some improvements on your working version:
import Data.List
import Data.Function(on)
ks = knapsack []
knapsack :: [(Int, Int)] -> [(Int, Int)] -> Int -> [(Int, Int)]
knapsack xs [] _ = xs
knapsack xs ys max =
foldr (maxOf) [] (xs: [knapsack (y:xs) (delete y ys) max
| y <- ys, weightOf(y:xs) <= max ] ) where
weightOf = sum . map snd
maxOf :: [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
maxOf a b = maximumBy (compare `on` valueOf) [a,b] where
valueOf = sum . map fst
Might I suggest using a dynamic programming approach? This way of solving 0-1 knapsack problems are almost painfully slow, at least when the amount of variables gets larger than around 20. While it's simple, it's just too ineffective. Here's my shot at it:
import Array
-- creates the dynamic programming table as an array
dynProgTable (var,cap) = a where
a = array ((0,0),(length var,cap)) [ ((i,j), best i j)
| i <- [0..length var] , j <- [0..cap] ] where
best 0 _ = 0
best _ 0 = 0
best i j
| snd (var !! (i-1)) > j = a!decline
| otherwise = maximum [a!decline,value+a!accept]
where decline = (i-1,j)
accept = (i-1,j - snd (var !! (i-1)))
value = fst (var !! (i-1))
--Backtracks the solution from the dynamic programming table
--Output on the form [Int] where i'th element equals 1 if
--i'th variable was accepted, 0 otherwise.
solve (var,cap) =
let j = cap
i = length var
table = dynProgTable (var,cap)
step _ 0 _ = []
step a k 0 = step table (k-1) 0 ++ [0]
step a k l
| a!(k,l) == a!(k-1,l) = step a (k-1) l ++ [0]
| otherwise = step a (k-1) (l - snd (var !! (k-1))) ++ [1]
in step table i j
In the input (var,cap), var is a list of variables in the form of 2-tuples (c,w), where c is the cost and w is the weight. cap is the maximum weight allowance.
I'm sure above code could be cleaned up to make it more readable and obvious, but that's how it turned out for me :) Where the code snippet by Landei above is short, my computer took ages computing instances with only 20 variables. The dynamic programming approach above gave me a solution for 1000 variables faster.
If you don't know about dynamic programming, you should check out this link:Lecture slides on dynamic programming, it helped me a lot.
For an introduction to arrays, check out Array tutorial.