1

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?

6
  • 2
    Why do you think that should work? Commented Jul 31, 2017 at 15:12
  • I got a mistake, now when I'm typing fmap (+3) Sure 1, it shows Sure 4. Commented Jul 31, 2017 at 15:16
  • Actually I want a general way to unbox Unsure then I can do something such as fmap (==) 100 (Sure 100). Commented Jul 31, 2017 at 15:19
  • 3
    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. Commented Jul 31, 2017 at 15:34
  • 1
    You can already do this, you just need to bring the 100 inside the parentheses: fmap (==100) (Sure 100) <-- returns Sure True. Commented Jul 31, 2017 at 15:34

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

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).

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.