1
votes

I'm a beginner of Haskell. Now I tried to define a data as following:

data Unsure a = Sure a |Error [Char]
 deriving (Show)

then tried to implement Functor like this:

instance Functor Unsure where
    fmap f (Sure x) = Sure (f x)
    fmap f (Error e) = Error e

In my opinion, fmap should work Once I implemented Functor for Unsure. So I can use fmap to do something like:

fmap (+3) (+100) Sure 1

The result was supposed to be Sure 104 , in fact I got a error

• Non type-variable argument in the constraint: Num (Unsure a) (Use FlexibleContexts to permit this) • When checking the inferred type it :: forall a. (Num (Unsure a), Num a) => Unsure a

Any suggestion?

3
Why do you think that should work?Willem Van Onsem
I got a mistake, now when I'm typing fmap (+3) Sure 1, it shows Sure 4.dannybaobei
Actually I want a general way to unbox Unsure then I can do something such as fmap (==) 100 (Sure 100).dannybaobei
This is an interesting error! If you had written fmap (+3) (Sure 1) things would have worked, as would have fmap (+3) (+100) 1 (for subtle reasons). If you had written fmap (+3) Sure 1 you might have gotten a reasonable error message, but fmap (+3) (+100) Sure 1 is a perfect storm that creates a nasty error message.cody
You can already do this, you just need to bring the 100 inside the parentheses: fmap (==100) (Sure 100) <-- returns Sure True.Fyodor Soikin

3 Answers

3
votes

You probably intended to write fmap ((+3) . (+100)) (Sure 1) or fmap (+3) $ fmap (+100) (Sure 1).

1
votes

fmap is a function that has the type fmap :: Functor f => (a -> b) -> f a -> f b.

In words, the function fmap takes two arguments: The first argument is a function of from a type a to b. The second argument is a value of a Functor of type a. The result is a Functor of type b.

In your example you write: fmap (+3) (+100) Sure 1. In this example fmap has four arguments: First is (+3) , second is (+100), third id Sure and fourth is 1.

As written by @Brian Olivier to make one argument out of (+3) and (+100) you can combine them with the (.) operator and put this expression into parenthesis. This then gives you the first argument of fmap.

Then you have to put Sure 1 into parenthesis to get the second argument of fmap.

So all together you have to write fmap ((+3) . (+100)) (Sure 1).

0
votes

In addition to what others have said, if you add use the DeriveFunctor language extensions (eg via the {-# LANGUAGE DeriveFunctor #-} pragma) you can just derive functor:

data Unsure a = Sure a |Error [Char]
  deriving (Show, Functor)