最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typeclass - Showing Functor result in Haskell - Stack Overflow

programmeradmin2浏览0评论

I have defined the following Functor with the following type class ...

-- Let's suppose we want to create a functor that
-- performs the opperation :
--
-- fmap inc (Strength 3)

data Stat a = Strength a | Agility a | Constitution a
          deriving Show

instance Functor Stat where
  -- fmap :: (a -> b) -> Stat a -> Stat b
  fmap g (Strength str)     = Strength (g str)
  fmap g (Agility agi)      = Agility (g agi)
  fmap g (Constitution con) = Constitution (g con)

-- Then it can be called as fmap inc (Strength 3)

-- Let's suppose I use a Type class for this function

class Inc a where
  incStat :: (Num a) => a -> a

instance Inc (Stat a) where
  incStat (Strength a) = Strength a

-- instance Show a => Show (Stat a) where
--   show (Strength a) = show (a)
--   show (Agility a) = show (a)
--   show (Constitution a) = show (a) 

It builds ok, but when I try to do the following command

fmap incStat (Strength 3)

I'm getting the following error I don´t fully understand

<interactive>:62:1: error:
• Ambiguous type variable ‘b0’ arising from a use of ‘print’
  prevents the constraint ‘(Show b0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘b0’ should be.
  Potentially matching instances:
    instance Show Ordering -- Defined in ‘GHC.Show’
    instance Show a => Show (Stat a)
      -- Defined at characteristicsFunctor.hs:9:24
    ...plus 26 others
    ...plus 12 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it

Can you help me ? What is the error saying ?

NOTE : take IncStat as identity . I`m just checking the structure of the script

I have defined the following Functor with the following type class ...

-- Let's suppose we want to create a functor that
-- performs the opperation :
--
-- fmap inc (Strength 3)

data Stat a = Strength a | Agility a | Constitution a
          deriving Show

instance Functor Stat where
  -- fmap :: (a -> b) -> Stat a -> Stat b
  fmap g (Strength str)     = Strength (g str)
  fmap g (Agility agi)      = Agility (g agi)
  fmap g (Constitution con) = Constitution (g con)

-- Then it can be called as fmap inc (Strength 3)

-- Let's suppose I use a Type class for this function

class Inc a where
  incStat :: (Num a) => a -> a

instance Inc (Stat a) where
  incStat (Strength a) = Strength a

-- instance Show a => Show (Stat a) where
--   show (Strength a) = show (a)
--   show (Agility a) = show (a)
--   show (Constitution a) = show (a) 

It builds ok, but when I try to do the following command

fmap incStat (Strength 3)

I'm getting the following error I don´t fully understand

<interactive>:62:1: error:
• Ambiguous type variable ‘b0’ arising from a use of ‘print’
  prevents the constraint ‘(Show b0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘b0’ should be.
  Potentially matching instances:
    instance Show Ordering -- Defined in ‘GHC.Show’
    instance Show a => Show (Stat a)
      -- Defined at characteristicsFunctor.hs:9:24
    ...plus 26 others
    ...plus 12 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it

Can you help me ? What is the error saying ?

NOTE : take IncStat as identity . I`m just checking the structure of the script

Share Improve this question edited Mar 11 at 15:55 Noughtmare 10.8k1 gold badge17 silver badges41 bronze badges asked Mar 11 at 15:37 YagoYago 4271 gold badge4 silver badges19 bronze badges 8
  • Why do you think it should be fmap incStat (Strength 3) instead of incStat (Strength 3)? – Louis Wasserman Commented Mar 11 at 15:49
  • If you use fmap f k, then f operates on k's guts. But your incStat does not operate on Stat's guts, it operates on Stat itself. – n. m. could be an AI Commented Mar 11 at 15:55
  • I just want to note that it is not just you, the error message confusing because it is leaking implementation details of GHCi, so it is not surprising if you don't understand it. – Noughtmare Commented Mar 11 at 16:05
  • I want to use the operation incStat with the functor . Maybe can look as over engineering but it's just an exercise – Yago Commented Mar 11 at 16:23
  • It is not over engineering. It just does not make any sense. – n. m. could be an AI Commented Mar 11 at 17:40
 |  Show 3 more comments

1 Answer 1

Reset to default 4

incStat already understands your functor, it does not need fmap to teach it how. So you may either use incStat directly, without fmap:

> incState (Strength 3)
Strength 3

or you may use fmap directly, without incStat:

> fmap (1+) (Strength 3)
Strength 4

To encapsulate this version you may like to define incStat in terms of fmap:

instance Num a => Inc (Stat a) where
    incStat = fmap (1+)

If you insist on using both incStat and fmap, then you must have an outer functor for the fmap to operate on -- which, if you like, may again be Stat.

> fmap incStat [Strength 3, Strength 4]
[Strength 3, Strength 4]
> fmap incStat (Agility (Strength 3))
Agility (Strength 3)

As an aside, the Num constraint in your Inc declaration is almost certainly a mistake. I recommend deleting it.

class Inc a where incStat :: a -> a

The Num constraints are better placed on the instances, where they are used.

instance Num a => Inc (Stat a) where
    incState (Strength a) = Strength (1+a)
发布评论

评论列表(0)

  1. 暂无评论