1.
phantom type 虚幻类型
2.
把满足的结果输出出来
solutions :: Formula ts -> [ts] solutions (Body body) = [()] solutions (Forall [] as) = [] solutions f@(Gorall (x:xs) as) | satisfiable f = [(x, fs) | fs <- solutions (as (Con x))] ++ solutions (Forall xs as) | otherwise = [] solutions (Exist [] as) = [] solutions (Exist (x:xs) as) = [(x, fs) | fs <- solutions (as (Con x)), satisfiable (as (Con x))] ++ solutions (Forall xs as) > solutions ex4 [(1, (False, ())), (1, (True, ())), (2, (True, ()))]
可以看到,通过GADT我们可以限定构造器返回的类型, 这样各种运算符的返回类型就可以在编译器就检查了。表达式的类型也通过嵌套的元组来表示需要哪些类型的集合。
3.
contriaint
4.
kind signatures
This proposal adds standalone kind signatures allowing users to declare the kind of type-level declarations introduced with
type
, data
, newtype
, or class
.type MonoTagged:: Type-> Type-> Type data MonoTagged t x= MonoTagged x type Id:: forall k. k-> k typefamily Id xwhere Id x= x type C:: (k-> Type)-> k-> Constraint class C a bwhere f:: a b type TypeRep:: forall k. k-> Type data TypeRep awhere TyInt:: TypeRep Int TyMaybe:: TypeRep Maybe TyApp:: TypeRep a-> TypeRep b-> TypeRep (a b)
Declarations that have a standalone kind signature (with no wildcards) can use polymorphic recursion
declarations without such signatures are understood to have inferred kinds, and polymorphic recursion is not available. Note that the last example above.
TypeRep uses polymorphic recursion and would be rejected without the standalone kind signature.
This proposal replaces GHC’s current notion of syntactic CUSKs
5.
Haskell中常见的类型类: Ord, Bounded, Enum, Show
实现Ord类型至少需要定义compare或者≤函数
索引类型类Ix 是把连续的值映射到证书的一种类型类
P249
show函数 showsPrec函数
showsPrec :: Show a => Int -> a -> ShowS
6.
函子类型类 Functor
functor需要一个类型f作为参数,这个类型的kind为*→*,即它是一个类型构造器
比较functor与Applicative中二元运算符的区别
(<$>) :: (a->b)->f a -> f b (<*>) :: f (a -> b) -> f a -> f b
applicative类型类除了具有Functor的特性外,能做的只是调用函子容器内的函数
常常把这个类型类称作可应用函子(Applicative Functor),意为可应用函数的函子
7.
实现的Applicative类型类实例应该满足定律
单位元(identity)pure id <*> v = v
8.
同态定律(homomorphism)
pure f <*> pure x = pure (f x)
互换定律(interchange)
u <*> pure y = pure ($ y) <*> u
9.
选择可应用函子 Alternative
infixl 3 <|> class Applicative f => Alternative f where empty :: f a (<|) :: f a -> f a -> f a
<|>运算符意为其他的选择
当给定多个值的时候,需要选择合理的
Alternative类型类中还定好了另外两个函数some与many定义,使用了Applicative的<*>与Alternative的<|>运算符
some :: f a -> f [a] some v = some_v where many_v = some_v <|> pure [] some_v = (:) <$> v <*> many_v many :: f a -> f [a] many v = many_v where many_v = some_v <|> pure [] some_v = (:) <$> v <*> many_v
这两个函数是我们定义了empty与(<|>)免费得到的
一个字符分析器类型可以定义:
newtype Parse a = Parser {runParser :: String -> Maybe (a, String) }
10.
字符串类型类 IsString
IsString类型类定义在Data.String模块下,引入这个类型类的原因是Haskell需要支持各种字符串类型,因为默认的字符类型String串显然是不高效的,它是一个字符的单链表,在做有些操作时候是不高效的
11.
语言扩展DeriveAnytClass(DAC), GeneralizedNewtypeDeriving (GND) 还有默认的类型类到处之间是有冲突的
stock newtype anyclass
stock: 表示GHD可以导出的哪些Haskell2010语言标准中规定可导出的类型类,如Eq, Show, Enum 等还有其他类型类、
newtype: 表示应用GND语言扩展导出类型类实例
anyclass: 表示应用DAC语言扩展类导出类型类实例
- 模板元编程(template meta-programming)
-- derive.hs {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -ddump-splices #-} import Data.Derive.Class.Arities import Data.Derive.Arities import Data.Derive.Show import Data.Derives.Eq import Data.DeriveTh data Shape = Circle Double | Triangle Double Double Double derive makeEq ''Shape derive makeShow ''Shape derive makeArities ''Shape
TemplateHaskell语言扩展
DriFT工具
2.
Monoid
semigroup 半群 是闭合于一个有结合性质的二元运算之下的集合S构成的代数结构。
3.
newtype First a = First {getFirst :: Maybe a} instance Monoid (First a) where mempty = First Nothing r@(First (Just _)) `mappend` _ = r First Nothing `mapped` r = r
4.
半群类型类Semigroup
{-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ >= 702 #define LANGUAGE_DefaultSignatures {-# LANGUAGE DefaultSignatures #-} #endif import Data.Monoid infixr 6 <> class Semigroup a where (<>) :: a -> a -> a #ifdef LANGUAGE_DefaultSignatures default (<>) :: Monoid a => a -> a -> a (<>) = mappend #endif
逆函数(inverse function)
可交换群(abelian group)类型类
5.
可游历类型类Traversable
ExistentialQuantification语言扩展
evalSeq :: Maybe Integer -> (Integer -> Maybe Integer) -> Maybe Integer evalSeq mi f = case mi of Nothing -> Nothing Just a -> f a
6.
Maybe monad 与Identify monad
instance Applicative Maybe where pure = Just Just f <*> Just a = Just (f a) _ <*> _ = Nothing instance Monad Maybe where return = Just (Just a) >>= f = f a Nothing >>= _ = Nothing fail _ = Nothing
7.
Functor, Applicative与Monad的关系 P328
上下文相关(context sensitive)
8.
class (Functor t, Foldable t) => Traversable t where {-# MINIMAL traverse | sequence #-} traverse :: Applicative f => (a -> f b) -> t a -> f (t b) traverse f = sequenceA . fmap f sequenceA :: Applicative f => t (f a) -> f (t a) sequenceA = traverse id mapM :: Monad m => (a -> m b) -> t a -> m(t b) sequence :: Monad m => t (m a) -> m (t a) sequence = sequenceA
chapter 11 系统编程及输入/输出
不纯函数与副作用
pure function
透明性(referential transparency)可以演绎一个纯函数的运行过程来推导出唯一确定的结果
Data.IORef 模块中提供了IORef容器来以及相应的函数来直接引用或者修改i容器内部的值,可称为IO引用
-- bool.hs import Data.IORef bool :: IO() bool = do bRef <- newIORef True modifyIORef bRef not b <- readIORef bRef not print b > bool False True
sequence_ 时则不会出现最后的结果的列表,返回的结果只是()
Monad相关函数名中最后的下划线可以理解为将结果省略掉
forM :: Monad m => [a] -> (a -> m b) -> m [b] forM_ :: Monad m => [a] -> (a -> m b) -> m ()
MonadReader
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} ... class (Moad m) => MonadReader r m | m -> r where ask :: m r local :: (r -> r) -> m a -> m a instance MonadReader r (Reader r) where ask = Reader id local f m = Reader $ runReader m . f test :: Reader [Int][Int] test = do xs <- local (map(+1)) ask ys <- ask return ys
ntAux是辅助函数