Regarding list of tuples and file - haskell

I need to take the list of tuples from a file and multiple 2nd a 3rd values of each tuple. For example: [(1,"A", 100,2),(2,"B", 50,3)] . I need to find 100*2=200 and 50* 3=150. I only want to display the final total. That is 350. I am taking the list of tuples from a file. I am getting an error lik this:
- Type error in generator
*** Term : generator c
*** Type : Int
*** Does not match : IO a
Code is given below.
type Code=Int
type Price=Int
type Quantity=Int
type Name=String
type ProductDatabase=(Code,Name,Price,Quantity)
bill=do
b<-cart_list_returner
let c :: [ProductDatabase]
c = b
w<-generator c
let r :: String
r = w
putStrLn r
generator::[ProductDatabase]->Int
generator c=foldl (\a (id,x, y, z) -> a + y*z) 0 c
I just want the program to take the list of tuples in file and produce the total amount. Some one plz help me. thanks in advance

Use the <- binding operator only when you want to run an IO function.
For giving names to results of pure functions, use let.
generator is a pure function --- its result is of type Int, not of type IO Int.
So replace the line
w<-generator c
with
let w = generator c

Related

GHCI vs compiled function difference

The goal is to input a float and return a string containing only the absolute value of the digits before the dot.
Basically putting in -14.4 should return "14"
When I type in the sequence of instructions via GHCI I run into no problem.
Yet when I use it in a compiled function like this:
testFront :: Float -> String
testFront x = tillDot $ show $ abs $ x
tillDot :: String -> String
tillDot x = case x of
[] -> ""
x -> takeWhile (/= '.') x
then suddenly I run into the error shown in the the screenshot.
I figured out that I had to put the negative number using ().
The question is: Can I somehow do this within the file? Something that automatically puts my input into ()? Or do I have to write a seperate function that does that?
The question is: Can I somehow do this within the file? Something that automatically puts my input into ()? Or do I have to write a seperate function that does that?
The reason you need to wrap these into parenthesis is because there is a difference between:
f - 14
and:
f (-14)
Indeed, for the former it will subtract 14 from the value of a variable named f. If f is for example 25, it will return 11.
For the latter it will call a function f with -14 as argument.
Except for a minus, no operator has an unary form. The parenthesis are thus necessary to disambiguate between the unary and binary form.

How to implement static scope, dynamic scope, and lazy evaluation in ml and haskell?

I understand conceptually what all of these are, I'm just hoping for some code examples of how to implement them in ML and Haskell.
Haskell variables (top level definitions, variables in patterns, etc.) are all statically scoped. For example, the program:
y = "global value"
f = print y
g = let y = "local value" in f
main = g
will print "global value". Even though, in the definition of g, the function f is used after "redefining" y, this redefinition doesn't affect the definition of f which uses the statically (AKA lexically) scoped definition of y in force where f was defined.
If you want to "implement" dynamic scope, you have to be more specific about what you really mean. If you're wondering if you can write a function in plain Haskell, like:
addY :: Int -> Int
addY x = x + y
such that y might refer to a different variable from one call to the next, then the answer is no. In this definition, y always refers to the same variable (which, in Haskell, means the same, immutable value) which can be determined by static analysis of the program and cannot be dynamically redefined.
[[Edit: As #Jon Purdy points out, though, there's a Haskell extension that supports a form of dynamic scope such that the following prints various dynamically scoped local values with the same function.
{-# LANGUAGE ImplicitParams #-}
f :: (?y :: String) => IO ()
f = print ?y
g = let ?y = "g's local value" in f
h = let ?y = "h's local value" in f
main = do
g -- prints g's local value
h -- prints h's local value
let ?y = "main's local value" in f -- prints main's value
--end of edit--]]
For lazy evaluation, there are many examples, such as the following entered into an interactive GHCi session:
take 3 [1,2..] -- gives [1,2,3]
let x = (15^2, 6 `div` 0)
fst x -- gives 225
let y = snd x
y -- *** Exception: divide by zero
In the first line, if the evaluation was strict, the attempt to fully evaluate the infinite list [1,2..] (can also be written [1..] -- just counts up 1,2,3,.. forever) would go into an infinite loop, and the take function would never be called. In the second example, if evaluation was strict, the division by zero error would occur when x was defined, not only after we tried to print its second component.

parse error on input ‘::’ when making an explicit type definition for a function which accepts multiple arguments

I am working on a project in Haskell for the first time and I am working on translating over my ADT into the code properly, however when I am writing the explicit type definitions for my functions and I load my code in GHCi I get the following error:
Blockquote parse error on input ‘::’
The line in question is for a function called type which accepts a character and a tuple and returns a tuple as shown below:
type :: validChars -> tuple -> tuple
where validChars is the list of valid characters, the definitions for my lists are shown here if this helps:
tuple = (l, r, b, k)
l = [l | l <- validChars]
m = [m | m <- validChars]
b = [b | b <- validChars]
k = [k | k <- validChars]
validChars = [ chr c | c <-alphanumericChars , c >= 32, c <= 122]
alphanumericChars = [ a | a <- [0..255]]
I checked to make sure it wasn't validChars causing the error by replacing it with the Charstype as shown:
type :: Chars -> tuple -> tuple
But I still get the same error, I am a complete beginner at Haskell so I'm probably missing something important, but I am not sure what that would be exactly; I've looked at answers for similar questions I have been unsuccessful thus far. Any help with this would be appreciated.
type is a keyword in Haskell, so you can't use it as the name of your function.
Furthermore type names start with a capital letter in Haskell and anything starting with a lower case letter in a type is a type variable. So if you define myFunction :: validChars -> tuple -> tuple, that defines a function that takes two arguments of arbitrary types and produces a result of the same type as the second argument. It's the same as myFunction :: a -> b -> b.
If you write myFunction :: Chars -> tuple -> tuple, you get a function whose first argument needs to be of type Chars (which needs to exist) and the second argument is of an arbitrary type that is also the type of the result. Again it's the same as myFunction :: Chars -> a -> a.
Note that for this to work, you'll actually have to have defined a type named Chars somewhere. If you want to take a list of Chars, the type should be [Char] instead.
And if you want the second argument and result to actually be tuples (rather than just a type variable arbitrarily named tuple), you need to specify a tuple type like (a,b,c,d), which would accept arbitrary 4-tuples, or something specific like (Integer, String, String, String), which would accept 4-tuples containing an Integer and three Strings.

Haskell - passing a function as a argument compilation error

I have a very simple function called 'fold' that takes a function f and executes it. Given a function 'add' and two numbers it calls add with those two numbers and displays the results. However I cannot compile it due to a compilation error below. What is the error specifically stating and what can I do to solve it?
module Main where
add x y = x + y
--fold :: ((a,b)->c) -> a->b->c
fold f n x = f n x
main :: IO ()
main = do
fold add 2 3
The problem is that you've declared main (correctly) as having type IO (), but fold doesn't return that. The error message is a little more complicated because in theory, add (and thus fold) could return a value of type IO (), since add can return any type with a Num instance. IO (), however, is not an instance of Num. The solution is to return an IO action created from the return value of fold. One way to do that is to use the print function (which takes any value with a Show instance and converts it to a String before outputing it).
main = print $ fold add 2 3

searching in sorted Indexes of tuple list by bubble sort in haskell

I choice binary search for index of array of record ascasestudy for my graduate research by c++ and haskell I write the c++ code and work and now I work for the haskell one
import Data.List
data BookInfo = Book Int String [String]
deriving (Show)
--Entering the variables
entering :: Int String [String]-> Book
entering id name subject= Book id name subject
--make an idex of the array of tuples
index :: [Book]->[Int]
index [m] = getID (Book id _ _ ) = id
main :: IO ()
main = do
putStrLn "Please enter your book id,name,Subject"
Book inpStr <- getLine
putStrLn print r
-- BubbleSort using map
bubbleSort ::(Ord x) => [x] -> [x]
bubbleSort (x':xs) = if x>x' then x': bubbleSort(x:xs)
else
if x<x' then x: bubbleSort(x':xs)
else
x: bubbleSort(X':xs)
bubble ::[a] -> [a]
bubble [a] = map bubbleSort [a]
--Make index for the array
indexsort(ord a)::[int]->[Int]
indexsort a=bubble a
--Make the list of tuples
addBooks2List Book->[Book]->[Book]
addBooks2List b m=b:entering b':m
--binarysearch
binarysearch [Int]->Int->Int->Int->Int
a=bubble x
binaryseach a i m j=
let u=(i+m)/2
if a[u]=j then u
if a[u]>j then binaryseach a i u-1 j
else
if a[u]<j then binarysearch a u+1 m j
if i=m "Not found"
--printing the tuple that has the searched id
print::Int->Book
print r= Book r y z
r=binaryseach m 0 (length m)
it made an error at 8:3 parse error on input 'entering' what this error mean? and how I can correct it ?
For one thing, the type signature for entering should read
entering :: Int -> String -> [String] -> BookInfo
rather than entering :: Int String [String]-> Book—but that's a type error, not a parse error.
Perhaps your indentation is wrong, but that's hard to tell without having your code available verbatim. Remember: in Haskell, as opposed to languages such as C and Java, the layout of your code matters.
Anyway, the code, as you have posted it, is far from a working solution for your problem. You may want to take a few steps back and study how to write elementary functions in Haskell and then, later, how to glue them together in order to get at more involved programs. I really doubt whether learning the language by trying to convert snippets of C++ into Haskell has a high chance of success. Just my two cents, though...
There are so many problems in your code, you best start with a single function and grow your program slowly and see that you get the incremental pieces compiled. Starting with this:
entering :: Int String [String]-> Book
entering id name subject= Book id name subject
First, Book is not a type but a data constructor, the type is BookInfo. Then, you're missing the arrows (as dblhelix pointed out). So it should read:
entering :: Int -> String -> [String]-> BookInfo
entering id name subject= Book id name subject
This will compile. However, entering now is just the same as Book. Anyway, continue with adding the next function and getting it compiled and so on.
If we go on,
index :: [Book]->[Int]
index [m] =
The definition is missing (what's on the right-hand side of =?), and [m] will only match a lists with a single element which is probably not what you want. Complete this function, or comment it out and continue with the rest. Apparently you don't use it at all currently. And so on.

Resources