I'm currently learning OCaml and I don't get along with the syntax. I didn't find any fitting advice in the web.
I basically want to call a function and reuse the result from it in the same function.
find_by_name is a function which finds the food by its name
ingredients is part of the record and a list
avg is a function which calculates the average
My function currently looks like that: It's terribly wrong but I don't know what to change.
let avg_veggie_kcal name fd = find_by_name name fd -> avg x.ingredients
You can use a local let binding let ... = ... in ... to name intermediary results of some computation:
let some_function input =
let intermediary_result = first_computation_step input in
second_computation_step intermediary_result
let avg_veggie_kcal name fd =
match find_by_name name fd with
x -> avg x.ingredients
...assuming find_by_name returns a record with an ingredients field, and the ingredients field is of the input type to avg.
Related
LOAD
if(Year(max(FISCAL_YEAR))=Year(Today()),
Year(max(FINANCIAL_YEAR))) as Curr_FY,
if(Year(max(FISCAL_YEAR))=Year(Today()),
Year(today()-1)) as Prev_FY
Resident [data_table];
Let Current_FY = '=Curr_FY';
Let Last_FY = '=Prev_FY';
I want to create Dynamic variable for current FISCAL_YEAR and last FISCAL_YEAR
If the table contains only a single value for Curr_FY and Prev_FY then you can use peek script function to get the value in a variable
Let Current_FY = peek('Curr_FY');
Let Last_FY = peek('Prev_FY');
Bear in mind that if there are multiple values then peek will return the last loaded value
I have been trying to a read file creating data in haskell. i have the following data type constructed:
data Participant = Participant {name:: String, age:: Int,
country:: String, }
The text file i have is in this format
Jack 21 England
Natalie 20 France
Sophie 24 France
Each word corresponds to name age and country respectivly. I want to read the file and create a list of participants. But IO:String seem to be a pain in the neck. Do you have a suitable soliton for this problem.
IO isolation is not a defect, but a feature of Haskell, and one of its clear success.
If you want to serialize data to file, and load data back into your program, you don't have to do that by hand. Use any serializing library, there are many of them. You can also use the great Aeson library, that can convert your data in JSON and load them back.
If you want to do that by hand for any reason, you must first define your own file format, and have it unambiguous. For example, what happens on your example if name contains a space ?
Then you should define a function that can parse one line of your file format and produce a Participant readParticipant :: String -> Maybe Participant. Notice the maybe, because if the string is ill-formated, your function won't be able to create a participant out of its hat, so it will produce a Nothing.
Then you can have a function that parse a list of participants (notice the plural) readParticipants :: String -> [Participants]. No Maybe here because the list itself allows for failure.
Now you can have a tiny IO function that will read the file content, and run readParticipants on it.
readParticipantsIO :: IO [Participants]
readParticipantsIO = readParticipants <$> readFile "participants.data"
-- alternative definition, exact same behaviour in this case
readParticipantsIO :: IO [Participants]
readParticipantsIO = do
content <- readFile "participants.data"
return $ readParticipants content
The lines and words functions can be used to split the string into a list of strings, and then you can package these strings into a list of Participant.
import Text.Read (readMaybe)
data Participant = Participant { name :: String, age :: Int, country :: String }
parseParticipants :: String -> [Participant]
parseParticipants fileContents = do
[name', age', country'] <- words <$> lines fileContents
Just age'' <- return (readMaybe age')
return (Participant { name = name', age = age'', country = country' })
main :: IO ()
main = do
participants <- parseParticipants <$> readFile "yourfile.txt"
-- do things with the participants
return ()
This is a follow-up to this question:
flatMap and `Ambiguous reference to member` error
There I am using the following code to convert an array of Records to an array of Persons:
let records = // load file from bundle
let persons = records.flatMap(Person.init)
Since this conversion can take some time for big files, I would like to monitor an index to feed into a progress indicator.
Is this possible with this flatMap construction? One possibility I thought of would be to send a notification in the init function, but I am thinking counting the records is also possible from within flatMap ?
Yup! Use enumerated().
let records = // load file from bundle
let persons = records.enumerated().flatMap { index, record in
print(index)
return Person(record)
}
I have the following types and database:-
type Title = String
type Singer = [String]
type Year = Int
type Fan = String
type Fans = [Fan]
type Song = (Title, Signer, Year, Fans)
type Database = [Song]
songDatabase :: Database
songDatabase = [("Wrapped up", ["Olly Murs"], 2014, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
("Someone Like you", ["Adele"], 2011, ["Bill", "Jo", "Garry", "Kevin", "Olga", "Liz"]),
("Drunk in Love", ["Beyonce", "Jay Z"], 2014, ["tom", "Lucy"])]
I want to add a fan to the last tuple in the list. Do i do this through using addToAl or is there other methods i can use?
Do i have to search for the data and delete it and then add the data I want? or is there a way to just add for example, "John" to the fans in the someone like you tuple.
You can't add a tuple to an existing list, all values in Haskell are immutable. Instead, you can construct a new list that contains the values you want. The best way to accomplish this is to first write a function that can add a fan to a single film:
addFan :: Fan -> Song -> Song
addFan fan (title, singer, year, fans) = ???
Then you can write a function updates a particular song in the database:
addFanInDB :: Fan -> Title -> Database -> Database
addFanInDB fan songTitle [] = []
addFanInDB fan songTitle (song:db) = ???
Since this looks very much like homework, I'm not going to give you a full solution since that defeats the purpose of the assignment. You'll need to fill in the ??? yourself.
I performed my first query with a grouping function using the following code:
let dc = new TypedDataContext()
open MathNet.Numerics.Statistics
let newData = query { for x in dc.MyData do
where (x.ID = "number of type string")
groupBy x.Code into g
let average = query { for x in g do
averageBy x.Billed_Amt }
select (g, average) }
|> Seq.toList
System.Console.WriteLine(newData)
I am now wanting to calculate the standard deviation of the billed amounts in each group. However, when I try to reference the column, 'Billed_Amt,' like so
let sd = newData.Billed_Amt.StandardDeviation()
I receive the following error: "constructor or member 'Billed_Amt' is not defined."
I also tried newData.g.Billed_Amt.StandardDeviation(), in case I needed to reference the groups first, but I got the same error message referring to 'g'.
How do I overcome this?
I will say that I notice that the 'list' I created with the query claims to have 63 items. These would be the different group keys, not the rows of data themselves.
I feel like the research I have done online to solve this problem has just sent me in circles. Most of the resources online do not dumb it down enough for newbies like me. Any help would be appreciated.
Thank you!