Chillo
Chillo

Reputation: 97

Haskell Basic IO

I want to create a Haskell IO function that uses a function to add an item of a data type to a list, then print a list of those datatypes.

DataType = Str Str Int []

It will always add the same item to the list.

I have this so far:

myFn = putStrLn( listAll ( addData "a" "b" 2000 [] testDatabase ) )

But I get the following errors:

:20 Couldnt match type [Char] with Char, expected String, Actual [String]

Now this may be because listAll outputs a list of strings, and putStrLn can only handle one? But i'm not sure how i'd sort that out.

:19 Function "a" is applied to 3 arguments

But "a" is not a function, it is part of the data type I want to be added (much confusion).

Upvotes: 0

Views: 126

Answers (3)

Ørjan Johansen
Ørjan Johansen

Reputation: 18199

Your second error is because "a" "b" 2000 [] is parsed as a function application, with "a" as the function. You cannot create a value of a new datatype in Haskell just by listing its subfields like that... there needs to be a data constructor name first. Exactly what to write depends on exactly how you have defined your new data type, but say your type declaration is

data MyNewType = MyDataConstructorName String String Int [SomeTypeYouDidn'tMention]

Then the expression for making your value would be

addData (MyDataConstructorName "a" "b" 2000 []) testDatabase

Upvotes: 0

Lee
Lee

Reputation: 144206

You can use forM_ from Control.Monad:

import Control.Monad

myFn :: IO ()
myFn = forM_ (listAll ( addData "a" "b" 2000 [] testDatabase )) putStrLn

Upvotes: 2

Chris Taylor
Chris Taylor

Reputation: 47402

Your problem is that the function listAll returns [String], whereas putStrLn expects a String. You have essentially two options -

  1. Convert the [String] to String, for example by using concat or unlines

  2. Apply putStrLn to each element of the [String] in turn, by using something like mapM_

For option 1, you could write

main = putStrLn $ unlines $ listAll (addData "a" "b" 2000 [] testDatabase)

For option 2, you could write

main = mapM_ putStrLn $ listAll (addData "a" "b" 2000 [] testDatabase)

Upvotes: 4

Related Questions