Haskell programe fix - haskell

guys can you help me fix this code?
import Data.Char
import Data.List
-- 1 2 3 4 5 6 7 8
colors = [1,2,3,4,5]
--game :: [Integer] -> [Char]
game a = do
let black = test a color
white = (test2 a color) - black
let x = [a] ++ createScore black white
show x
test [] [] = 0
test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys
test2 a b = length (intersection a b)
intersection first second = [n | n <- first , isInfixOf [n] second]
createScore c b = [(take c (repeat 1) ++ take b (repeat 0))]
start = do
a <- getLine
let b = map read $ words a
--print b
game b
start
I have problem with IO and nonIO functions.
description of the program:
read data from line
convert data to List of int
call function game (which takes List of int like parametr)
make some calculation
print score
start again from 1
Problem is in function start and I have no idea how to fix it.
Thanks for help.

there are a few things that don't quite work with the code you've given us.
I'll work through the compile errors.
On first load we get a name error:
ex1.hs:10:26:
Not in scope: 'color'
Perhaps you meant 'colors' (line 6)
(and again at line 11)
Of course the compiler is correct and we just need to change the appropriate names to match.
Next we get the interesting one I assume you're referring to with regards to IO and non-IO functions:
ex1.hs:28:7:
Couldn't match type '[]' with 'IO'
Expected type: IO Char
Actual type: String
In the return type of a call of 'game'
In a stmt of a 'do' block: game b
In the expression:
do { a <- getLine;
let b = map read $ words a;
game b;
start }
The error is your use of game b in the IO block.
The type annotation you have commented out over the function definition of game is actually correct -- it is [Integer] -> [Char].
As such it's a pure function and we don't need to use the do notation to describe it like we would with something that deals with IO -- because you have used the notation here with an argument of a list, the do expression represents a computation in the context of a list, not an IO computation, so calling it from start has a type mismatch, it expects IO, but it has found [].
We can start fixing it up by turning game into a pure function, using a let-in expression.
game :: [Integer] -> [Char]
game a = let black = test a colors
white = (test2 a colors) - black
x = [a] ++ createScore black white
in show x
So now we have a function that returns the string of the input and it's score.
The compiler now gives the error Expected type: IO Char, Actual type: [Char], this is because we are still trying to use a non-IO expression in the main do block.
We can fix this by actually printing the string to stdout, just using print, so your original
--print b
game b
can just be
print $ game b
At this point the program compiles!
Unfortunately it's still not quite right, when we run this and type in a list of integers like 1 2 3 we get the exception ex1.hs:(14, 1)-(15,66): Non-exhaustive patterns in function test.
This one comes down to your definition of test as:
test [] [] = 0
test (x:xs) (y:ys)
Doesn't account for the possibility of one list being empty -- because the check is always between the head elements of the lists probably the smallest change to fix this could just be:
test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys
test _ _ = 0
And now the program compiles and executes. Hopefully that makes sense.

game is (or should be) a pure function, so you need to call it with a function that returns an IO value in your start function, e. g. print $ game b.
There is also no reason to use do notation there (you can because [a] is also a monad, but you don't take advantage of it in any way). You can just use game a = show x and replace the let statements with a where block (or use let ... in).
test should be able to deal with the case of one list being empty and the other not, or you need to ensure that both lists are always the same size.

Related

Haskell - Values do not save after a ForM loop

I want to be able to create a program in haskell that can an find an increasing subsequence from a list of numbers (not yet completed, this part is to compute for each sublist what the longest increasing subsequence is within that sublist). This program essentially take take from an input such as
1
5
1 2 9 6 8
where the first line is the number of test cases and the second line being the number of numbers in the specific test case, and the third line being the test case itself. It is looking for the multiple increasing sequences within the test case. Here is what I have so far:
main = do
inputCases <- getLine
let cases = (read inputCases :: Int)
forM [1..cases] $ \num -> do
inputNumbers <- getLine
let numbers = (read inputNumbers :: Int)
something <- getLine
let singlewords = words something
list = f singlewords
let hello = grid numbers numbers 0
let second = hello
print list
forM [0..numbers] $ \check -> do
forM [check..numbers] $ \check2 -> do
let val = 1
let keeper = val
forM [check..check2] $ \check3 -> do
let val = getVal hello list keeper check check2 check3
let keeper = val
return()
print check
print check2
print val
let hello = updateMatrix second val (check, check2)
let second = hello
f :: [String] -> [Int]
f = map read
grid :: Int -> Int -> a -> [[a]]
grid x y = replicate y . replicate x
getVal :: [[Int]] -> [Int] -> Int -> Int -> Int -> Int -> Int
getVal m b second x y z =
if b!!z < b!!y && 1+m!!x!!z > second then 1+m!!x!!z
else second
updateMatrix :: [[a]] -> a -> (Int, Int) -> [[a]]
updateMatrix m x (r,c) =
take r m ++
[take c (m !! r) ++ [x] ++ drop (c + 1) (m !! r)] ++
drop (r + 1) m
However, my problem is that once the program exits the ForM loop, it does not save the variable "hello" or anything that was declared in the for loop. Is there a better way of doing this? Would recursion work in this case? I am not quite sure how that would be implemented
lis[i][j] will hold the length of the longest increasing subsequence in {a[i], ..., a[j]}
here is the python code that I am trying to translate. Given this code, is there a better way of doing this besides the way I am currently trying to do it?
T = int(input())
for t in range(0, T):
n = int(input())
a = list(map(int, input().split()))
lis = [[0 for j in range(0, n)] for i in range(0, n)]
for i in range(0, n):
for j in range(i, n):
val = 1
for k in range(i, j):
if(a[k] < a[j] and 1 + lis[i][k] > val):
val = 1 + lis[i][k]
lis[i][j] = val
In my other answer, I discussed the answer to the question you asked about how to store information for retrieval later when in a forM loop. In this answer, I will discuss the idiomatic translation of for loops from other languages; generally this is not to produce a forM loop in Haskell.
Because this is an excellent programming exercise, I don't want to give away the answer -- there's a lot of joy and learning to be had from solving the problem yourself. But I do want to illustrate an alternative approach. To keep all the interesting bits of the translation I cooked up of your Python code, I will solve a slightly easier problem in a slightly stylized way: instead of lis[i][j] giving the length of the longest increasing subsequence between indices i and j in the original list, we will have lis[i][j] give the largest value between indices i and j in the original list.
The idea will go like this: instead of iterating over indices i and j, we'll iterate over suffixes starting at i, then over prefixes of suffixes starting at i and ending at j. To begin with, we'll do the naive thing of just calling maximum on each infix expression. So:
import Data.List
maxes0 a =
[ [ maximum inf
| inf <- tail (inits suff)
]
| suff <- init (tails a)
]
For example, we can try it on your example list in ghci:
> maxes0 [1,2,9,6,8]
[[1,2,9,9,9],[2,9,9,9],[9,9,9],[6,8],[8]]
Note right away that there's a difference in shape here: where in Python we produced a square result, here we produce a triangular one, omitting the useless entries that do not correspond to actual infix chunks of the original list. (It's easy to reintroduce dummy values if you actually need a square result for some reason.)
This is already pretty good, and quite idiomatic; however, there is one part of the Python code that it does not capture well yet: the Python code reuses previously computed values to do some dynamic programming. This can be done to the above code, as well, though it does require a bit of mental gymnastics the first few times you see it. We will use laziness and recursion to make available earlier results when computing later ones.
The idea here will be to keep a rolling max as we traverse the suffix, merging as we go the list of maximums of infixes with the new values we see in the suffix. So:
maxes1 a =
[ let row = head suff : zipWith max row (tail suff)
in row
| suff <- init (tails a)
]
We can see in ghci that this works just the same:
> maxes1 [1,2,9,6,8]
[[1,2,9,9,9],[2,9,9,9],[9,9,9],[6,8],[8]]
You can combine these two ideas (making the already-computed bits available via laziness+recursion, and making the infix list available by nested list comprehensions) to produce an idiomatic translation of the Python code which is completely pure, does not mention list indices anywhere, and does not use forM.
forM returns a list of values, one each per input element in the list it's handed, with whatever you compute in the body of the function you give to forM. So you can extract information from the loop body with the usual do-notation binding syntax. Here's a simple example that asks the user whether to double each number in a list:
import Control.Monad
vals = [1..5]
main = do
vals' <- forM vals $ \val -> do
v <- getLine
return (if v == "yes" then val*2 else val)
print vals'
An example of running it:
> main
yes
yes
no
no
yes
[2,4,3,4,10]
Though this example returned numbers for simplicity, you may return arbitrary information of interest from each loop iteration in this way.

Reading numbers from input Haskell

I want to have a function that reads arbitrary int's until the number '0' is inserted, and then presents the numbers inserted in an ordered list.
For that i wrote this function:
import Data.List
readIntegers :: IO()
readIntegers = do
putStrLn "insert a number: "
num<-getLine
let list = ordList ((read num :: Int):list)
if (read num == 0)
then print list
else readIntegers
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
This compiles just fine, but when i insert the number '0', it gives me this error:
*** Exception: <<loop>>
What am i doing wrong ?
As #phg points out, you are essentially constructing an infinite list, and actually evaluating it causes the loop error. A simple implementation to resolve this issue is to define a helper function which takes an additional parameter - a list to store all the inputs read in from the screen, like so:
readInteger :: IO ()
readInteger = readInteger' []
where
readInteger' x = do
putStrLn "insert a number: "
num<-getLine
if ((read num :: Int) == 0)
then print $ ordList x
else readInteger' $ (read num :: Int):x
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
Please note that the above is essentially just an implementation of #phg's answer, but with some changes to your original logic. Firstly, since 0 is a sentinel value, we shouldn't be appending that to our list. Second, we do not need to sort the list every single time we are adding a value to it. Sorting once at the time of printing/passing to another function is sufficient.
Demo
If you want to read an unspecified number of integers without prompting for user input and cut it off the moment you encounter 0, you would probably do well to use getContents, which will read everything from the standard input as a single string, lazily.
Then, it is a simple matter of parsing it to a list of numbers and doing what you want with it, like so:
readIntegers :: ()
readIntegers = do
a <- getContents
let b = ordList $ takeWhile (/= 0) $ map (\x -> read x :: Int) $ words a
mapM (putStrLn . show) b
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
let list = ordList ((read num :: Int):list)
This is basically a recursive definition of a list of the form [x, x, ...] (like if you wrote an equation saying x = 1 + x). That is perfectly fine by itself, since Haskell is lazy; however, if you try to print list (aka "solve the equation"), it will fail, since it will try to print infinitely many numbers.
You probably have a misconception about the workings of the (:) operator. Haskell functions will never perform an assignment operation and concatenate num onto list by changing it, like in imperative languages. There are only pure functions.
If you want to accumulate all numbers, you should try to come up with a recursive definition of readIntegers, keeping its state (the list) in an additional parameter (there are also more sophisticated ways, hiding the state passing, but more complicated to use for a beginner).
For a more sophisticated solution, note that this is an unfold and you can use unfoldM from Control.Monad.Loops to implement it:
import Control.Monad.Loops (unfoldM)
readInts :: IO [Int]
readInts = unfoldM $ fmap (check . read) getLine
where check x = if x == 0 then Nothing else Just x
This has the nice property that it returns the list in the order in which it was read.

How can I replace generators if I need only one result?

I'm playing with Haskell for first time.
I've created function that returns first precise enough result. It works as expected, but I'm using generator for this. How can I replace generator in this task?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
You can use the beautiful until function. Here it is:
-- | #'until' p f# yields the result of applying #f# until #p# holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
So, you can write your function like this:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
In your case, you do all the iteration and then compute a result just once. But until is useful even when you need to compute a result at each step - just use an (iter, result) tuple and then just extract the result at the end with snd.
It seems like you want to check higher and higher powers until you get one that satisfies a requirement. This is what you could do: First you define a function to get enough power, and then you integrate using that.
find gets the first element of a list that satisfies a condition – like being enough of a power! Then we need a fromJust to get the actual value from that. Please note that almost always, fromJust is a terrible idea to have in your code. However, in this case the list is infinite, so we will have troubles with infinite loops long before fromJust is able to crash the program.
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
The function
\xs -> take 1 xs !! 0
is called head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
Its use is somewhat unsafe, as shown it can throw an error if you pass it an empty list, but in this case since you can be certain your list is non-empty it's fine.
Also, we tend not to call these "generators" in Haskell as they're not a special form but are instead a simple consequence of lazy evaluation. In this case, preciseIntegrals is called a "list comprehension" and [0..] is nothing more than a lazily generated list.

Iterating through a String and replacing single chars with substrings in haskell

I am trying to learn some Haskell and I find it difficult. I am having some issues with my
current project. The idea is that I have to go through a String and substitute certain chars
with new substrings. For instance if I have a String "FLXF" and I want to replace every F
with a substring called "FLF" the result should be "FLFLXFLF". Now I have been working on this
specific problem for hours. I have been reading up on types, different functions that might come in handy (map, fold, etc) and yet I have not been able to solve this problem.
The code below is some of the different tries I have had:
apply :: String -> String
apply [] = []
apply (x:xs) = if (x == 'F')
then do show "Hello"
apply xs
else (apply (xs))
This example here I was just trying to show hello every time I encountered a 'F', but all it shows is "", so this clearly does not work. I am really not sure an if else statement is the way to go here. I was also thinking the function map might do the trick. Here the code I was thinking about could look something like this:
map (\x y -> if y == 'F' then "FLD" else y) "FLF"
but that gives me a type error. So as you can see I am lost. Excuse me my poor knowledge to Haskell, but I am still new to it. I really hope some of you can help me out here or give me a push in the right direction. Feel free to ask questions if I have been unclear about something.
Thank you in advance!
John
map (\x y -> if y == 'F' then "FLD" else y) "FLF"
This is nearly right.
First... why does the function take two arguments?
map (\y -> if y == 'F' then "FLD" else y) "FLF"
The remaining type error is because the then branch gives a String, but the else branch gives a Char (the two branches must each give a value of the same type). So we'll make the else branch give a String instead (recall that String is a synonym for [Char]):
map (\y -> if y == 'F' then "FLD" else [y]) "FLF"
Now the problem is that this gives you a [String] value instead of a String. So we'll concatenate all those strings together:
concat (map (\y -> if y == 'F' then "FLD" else [y]) "FLF")
This combination of concat and map is common enough that there's a standard function that combines them.
concatMap (\y -> if y == 'F' then "FLD" else [y]) "FLF"
concatMap is the most intuitive thing here. This kind of combination between mapping over a data structure a function that does itself return the type of the data structure (in this case, a list) and combining the results back into a single "tight" list is indeed very common in Haskell, and indeed not only for lists.
I'd like to explain why your first attempt compiles at all, and what it actually does – because it's completely different from what you probably think!
apply (x:xs) = if (x == 'F')
that line is still perfectly clear: you just take the first char off the string and compare it to 'F'. At bit "pedestrian" to manually take the string apart, but fine. Well, the name you gave the function is not particularly great, but I'll stick with it here.
then do show "Hello"
now this is interesting. You probably think do starts a list of points, "first do this, then do that"... like in simple Hello, World-ish example programs. But always remember: in Haskell, there's normally no such thing as an order in which stuff is calculated. That only happens in the IO context. But there's no IO in your code!?!
Not sure if you've heard about what IO actually is, anyway here you go: it's a Monad. Those "mythical Haskell constructs you've only read about in story books"...
Indeed, though this might lead a bit far here, this question covers all there is to know about Monads! How is that?
Here's another (correct!) way do define your function.
apply' str = do
x <- str
if (x == 'F')
then "FLF"
else return x
So I'm using this weird do syntax, and it's not in IO, and it looks completely different from what you'd write in IO, but it works. How?
x <- str
In do notation, variable <- action always means something like "take one value out of this monadic thingy, and call it x". What you've probably seen is something like
response <- getLine
which means "take a user input out of the real world (out of the IO monad!) and call it response". In x <- str, it's a string that we have, not an IO action. So we take a character out of a string – nice and easy!
Actually, it's not quite right, though. "take a character" is what you do with apply (x:xs) = ..., which simply takes the first one. In contrast, x <- str actually takes all possible characters out of the string, one by one. If you're used to procedural languages, this may seem very inconsistent with response <- getLine, but in fact it's not: getLine also consists of every possible input that the user might give, and the program has to act according to this.
if (x == 'F')
nothing unexpected here, but
then "FLF"
whoah! Just like that? Let's first look at the next line
else return x
ok, this looks familiar, but actually it's not. In other languages, this would mean "we're done with our function, x is the result". But that's obviously not what happens here, because x is Char, and the "return type" of apply' is String. In Haskell, return actually has little to do with returning values from a function, instead it means "put that value into the monadic context that we're working in". If the monad were IO, that would be quite the same: give this value back to the real-world context (this does not mean to print the value or something, just to hand it on). But here, our context is a string, or rather a list (of chars, so it is a String).
Right, so if x is not 'F' we put it back into the string. That sounds reasonable enough, but what about then "FLF"? Note that I can also write it this way:
if (x == 'F')
then do
x' <- "FLF"
return x'
else return x
which means, I take all characters out of "FLW" and return them back into the overall result. But there's no need to only think about the final result, we can as well isolate only this part do { x' <- "FLF"; return x' } – and, quite obviously, its value is nothing but the string "FLF" itself!
So I hope you have now grasped why apply' works. Back to your version, though it actually doesn't make much sense...
then do
show "Hello"
apply xs
here we have a line that's not at the end of a do block, but doesn't have a <- in it. You normally see this in IO in something like
main = do
putStrLn "How ya doin'?"
response <- getLine
...
Remember that "output-only" actions have type IO() in Haskell, which means, they don't directly return any meaningful value, just the trivial value (). So you don't really care about this, but you could still evaluate it:
main = do
trivial <- putStrLn "Hello, let's see what this IO action returns:"
print trivial
compiles and outputs
Hello, let's see what this IO action returns:()
It would be stupid if we had to do this evaluating () all the time, so Haskell allows to just leave the () <- out. It's really just that!
So a line like show "Hello" in the middle of a do block basically means "take one character out of show "Hello" (which is simply a string with the value "\"Hello\""), but don't do anything else with this character / just throw it away".
The rest of your definition is just other recursive calls to apply, but because none of them does anything more interesting than throwing away characters, you eventually end up at apply [] = [], so that's the final result: an empty string.
if-then-else... I know that Haskell supports these, however, I'm very surprised that no one here removed them...
So below are my solutions for different cases of making replacements.
Replacing a character
Replacing words
Replacing through a function on each word
$ cat replace.hs
import Data.List (isPrefixOf)
replaceC :: Char -> Char -> String -> String
replaceC _ _ [] = []
replaceC a b (x:xs)
| x == a = b:replaceC a b xs
| otherwise = x:replaceC a b xs
replaceW :: String -> String -> String -> String
replaceW a b s = unwords . map replaceW' $ words s
where replaceW' x | x == a = b
| otherwise = x
replaceF :: (String -> String) -> String -> String
replaceF f = unwords . map f . words
string = "Hello world ^fg(blue)"
main = do
print string
print $ replaceC 'o' 'z' string
print $ replaceW "world" "kitty" string
print . replaceF f . replaceW "world" "kitty" $ replaceC 'H' 'Y' string
where f s | "^" `isPrefixOf` s = '^':'^':drop 1 s
| otherwise = s
$ runhaskell replace.hs
"Hello world ^fg(blue)"
"Hellz wzrld ^fg(blue)"
"Hello kitty ^fg(blue)"
"Yello kitty ^^fg(blue)"
Your basic error was that you wanted to replace a Char in a String with a String.
This is impossible because String is a list of Char and a Char is a Char and not a short String. Neither is a String ever a Char, even if its length is 1.
Hence, what you really wanted is to replace some Char with some other Chars. Your approach was promising and could have been completed like so:
replace [] = [] -- nothing to replace in an empty string
replace (c:cs) = if c == 'F' then 'F':'L':'F':replace cs
else c:replace cs

Grab a string from a list and save it into another list?

I'm trying to grab a random item from a string list and save that into another string list but I can't get my code to work.
import System.Random
import Control.Applicative ( (<$>) )
food = ["meatballs and potoes","veggisoup","lasagna","pasta bolognese","steak and fries","salad","roasted chicken"]
randomFood xs = do
if (length xs - 1 ) > 0 then
[list] <- (fmap (xs!!) $ randomRIO (0, length xs -1))
else
putStrLn (show([list])
I'm getting parse error on input '<-' but I'm sure there are more issues then that. There is also the issue that the list may contain the same dishes two days in a row which is not what I want and I guess I can remove duplicates but that also would remove the number of items in the list which I want to stay the same as the number in the list.
Anyone have a good idea how I could solve this? I have been searching for a day now and I can't find something useful for me but that's just because I'm looking in the wrong places. Any suggestion on how I can do this or where I can find the info will be greatly appreciated!
The reason it didn't work is that you needed another do after your if...then. (After a then you need an expression, not a pattern <- expression.)
randomFood :: String -> IO () -- type signature: take a String and do some IO.
randomFood xs = do
if length xs > 1 then do
[list] <- (fmap (xs!!) $ randomRIO (0, length xs -1))
else
putStrLn (show([list])
But that still doesn't compile, because you don't actually do anything with your list.
At the end of every do block, you need an expression to return.
I think you meant to still print some stuff if the length of xs is too short, and you probably meant to print the selected food if there was more than one to choose from.
Better would be:
randomFood :: String -> IO ()
randomFood xs | length xs <= 1 = putStrLn $ show xs
randomFood xs | otherwise = do
item <- (xs!!) <$> randomRIO (0, length xs -1)
putStrLn $ show(item)
This | boolean test = syntax is better for conditional answers based on input.
I changed [list] to item because you're selecting a single item randomly, not a list of items.
Haskell is quite happy to let you put [list], because any string that's got one character in it matches [list].
For example, "h" = [list] if list='h', because "h" is short for ['h']. Any longer string will give you Pattern match failure. In particular, all the food you've specified has more than one character, so with this definition randomFood would never work! item will match anything returned by your randomRIO expression, so that's fine.
You imported <$> then didn't use it, but it's a nice operator, so I've replaced fmap f iothing with f <$> iothing.
I finally realised I'm doing the wrong thing with short lists; if I do randomFood ["lump of cheese"] I'll get ["lump of cheese"], which is inconsistent with randomFood ["lump of cheese"] which will give me "lump of cheese".
I think we should separate the short list from the empty list, which enables us to do more pattern matching and less boolean stuff:
randomFood :: String -> IO ()
randomFood [] = putStrLn "--No food listed, sorry.--"
randomFood [oneitem] = putStrLn . show $ oneitem
randomFood xs = do
item <- (xs!!) <$> randomRIO (0, length xs -1)
putStrLn . show $ item
This gives three different definitions for randomFood depending on what the input looks like.
Here I've also replaced putStrLn (show (item)) with putStrLn . show $ item - compose the functions show and putStrLn and apply ($) that to the item.
Few points to note :
Don't intermix pure and impure code.
Try to use library for a task rather than repeating what is already written.
Here is the code using random-fu library
import Data.Random
import Control.Applicative
food :: [String]
food = ["meatballs and potoes","veggisoup","lasagna","pasta bolognese","steak and fries","salad","roasted chicken"]
randomFood :: [String] -> RVar (Maybe String)
randomFood [] = return Nothing
randomFood xs = Just <$> randomElement xs
main :: IO ()
main = (sample $ randomFood food) >>= print
This is like choosing one element from a list randomly.
> main
Just "steak and fries"
> main
Just "meatballs and potoes"
If you want to output just a random permutation of the above list, you can use shuffle like
main = (sample $ shuffle food) >>= print
Example
> main
["meatballs and potoes","lasagna","steak and fries","roasted chicken","salad","pasta bolognese","veggisoup"]
> main
["roasted chicken","veggisoup","pasta bolognese","lasagna","steak and fries","meatballs and potoes","salad"]

Resources