poolhustler
poolhustler

Reputation: 51

fromJust Haskell

I'm having problems with converting a list of Maybes to a list of Strings.

My list looks something like this: [Nothing, Just 3, Just 9, Nothing, Nothing].

I want to replace all the Nothing's with dots ('.') and all the Just Int's with "Int".

My solution so far does not work.

 [if c == Nothing then c = '.' else show (fromJust c) | c <- [Nothing, Just 3.... etc] ]

I get this error message: parse error on input `='

I'm guessing I cant just give c the value of '.' like in Java or other languages.

Any ideas?

Upvotes: 3

Views: 2538

Answers (3)

leftaroundabout
leftaroundabout

Reputation: 120711

Your problem is that you're trying to use the list comprehension to modify elements in the list by doing c='.'. This is Haskell, so you never modify anything! (Well, except STRef or IORef, but let's leave that out).

[if c == Nothing then "." else show (fromJust c) | c <- [Nothing, Just 3.... etc] ]

does the trick: you don't have to specify that you want to replace c with ".", that's already implied by the use of the list comprehension itself. You just need to give that as the output value of the if statement.

(Note that I replaced '.' with ".", this is of course necessary because all elements of the output list must have the same type. show (fromJust c) necessarily has type String, so we can't just put Chars like '.' into the same list.)

But the alternative mentioned by Satvik and MathematicalOrchid is better. In Haskell, you generally try to avoid explicit if statements and suchlike if there's an alternative with higher-order functions from the standard libraries, like the maybe function. If writing explicit decisions yourself, you should prefer pattern matching over if, like

[ case c of
     Nothing -> "."
     Just number -> show number
 | c <- [Nothing, Just 3.... etc] ]

Upvotes: 8

MathematicalOrchid
MathematicalOrchid

Reputation: 62818

You can do the following:

[if c == Nothing then '.' else show (fromJust c) | c <- [Nothing, Just 3.... etc] ]

You don't need to write the c = part; just say what to return.

However, the thing you probably want here is the maybe function. It takes a value to replace Nothing with, and a function to apply when it's Just. In your case,

[maybe "." show c | c <- [...whatever...] ]

should do it. Or you can just do

map (maybe "." show) [...whatever...]

Whichever tickles your fancy. (IMHO, the latter is clearer.)

Upvotes: 8

Satvik
Satvik

Reputation: 11208

use maybe from Data.Maybe

import Data.Maybe

test = [Nothing, Just 3, Just 9, Nothing, Nothing]

f :: Show a => [Maybe a] -> [String]
f = map (maybe "." show)

Upvotes: 8

Related Questions