首页 > 解决方案 > Haskell 理解类型

问题描述

我一直在尝试使用 Haskell,并尝试了一些简单的列表推导。我只是偶然发现了我只能描述为使用 ghci 的奇怪行为。

这是我的输出:

GHCi, version 8.10.2: https://www.haskell.org/ghc/  :? for help
Prelude> l = [(b `div` 3, b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: Integral b => [(b, b)]
Prelude> take 50 l
[(1,3),(2,6),(3,9),(4,12),(5,15),(6,18),(7,21),(8,24),(9,27),(10,30),(11,33),(12,36),(13,39),(14,42),(15,45),(16,48),(17,51),(18,54),(19,57),(20,60),(21,63),(22,66),(23,69),(24,72),(25,75),(26,78),(27,81),(28,84),(29,87),(30,90),(31,93),(32,96),(33,99),(34,102),(35,105),(36,108),(37,111),(38,114),(39,117),(40,120),(41,123),(42,126),(43,129),(44,132),(45,135),(46,138),(47,141),(48,144),(49,147),(50,150)]
Prelude> 
Prelude> l = [('a', b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: Integral b => [(Char, b)]
Prelude> take 50 l
[('a',3),('a',6),('a',9),('a',12),('a',15),('a',18),('a',21),('a',24),('a',27),('a',30),('a',33),('a',36),('a',39),('a',42),('a',45),('a',48),('a',51),('a',54),('a',57),('a',60),('a',63),('a',66),('a',69),('a',72),('a',75),('a',78),('a',81),('a',84),('a',87),('a',90),('a',93),('a',96),('a',99),('a',102),('a',105),('a',108),('a',111),('a',114),('a',117),('a',120),('a',123),('a',126),('a',129),('a',132),('a',135),('a',138),('a',141),('a',144),('a',147),('a',150)]
Prelude> 
Prelude> l = [(b/3, b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: (Integral b, Fractional b) => [(b, b)]
Prelude> take 50 l

<interactive>:11: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.
      These potential instances exist:
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        ...plus 22 others
        ...plus 13 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In a stmt of an interactive GHCi command: print it
Prelude> 

'l' 的前两个定义是直截了当的,正是我所期望的。第三个没看懂。具体来说,为什么没有将类型定义为:

l :: (Fractional a, Integral b) => [(a, b)]

如果有人能解决我的困惑,我将不胜感激。

标签: haskelltypes

解决方案


正如@Willem Van Onsem 所指出的,元组的两个成员l是 的结果(/),其类型是Fractional a => a -> a -> a,因为它要求两个它的操作数都是相同的类型,这也决定了结果。


推荐阅读