zoukankan      html  css  js  c++  java
  • Haskell语言学习笔记(97)Phantom Type

    示例

    Named typeclasses in Haskell

    {-# LANGUAGE AllowAmbiguousTypes     #-}
    {-# LANGUAGE MultiParamTypeClasses   #-}
    {-# LANGUAGE FlexibleInstances       #-}
    {-# LANGUAGE ScopedTypeVariables     #-}
    {-# LANGUAGE TypeApplications        #-}
    
    module NamedTypeclass where
    
    import Prelude hiding (Monoid, mempty, (<>))
    
    data Sum
    data Product
    
    class Monoid b a where
      (<>)   :: a -> a -> a
      mempty :: a
    
    instance Monoid Sum Int where
      x <> y = x + y
      mempty = 0
    
    instance Monoid Product Int where
      x <> y = x * y
      mempty = 1
    
    instance Monoid b [a] where
      x <> y = x ++ y
      mempty = []
    
    fold :: forall b a . Monoid b a => [a] -> a
    fold []       = mempty @b
    fold (x : xs) = (<>) @b x (fold @b xs)
    
    sum :: [Int] -> Int
    sum = fold @Sum
    
    product :: [Int] -> Int
    product = fold @Product
    
    concat :: [[a]] -> [a]
    concat = fold
    
    *NamedTypeclass> NamedTypeclass.sum [1,2,3,4]
    10
    *NamedTypeclass> NamedTypeclass.product [1,2,3,4]
    24
    *NamedTypeclass> NamedTypeclass.concat [[1],[2]]
    [1,2]
    

    Phantom Type

    Phantom type
    WHAT I WISH I KNEW WHEN LEARNING HASKELL - Phantom Types

    AllowAmbiguousTypes

    {-# LANGUAGE AllowAmbiguousTypes #-}
    允许类型签名中的类型不出现在定义中,此时该类型为模糊(Ambiguous)类型,而所定义的类型被称为虚无(Phantom)类型。
    示例中
    class Monoid b a
    的 b 就没有出现在定义中,因而 b 是模糊类型,Monoid 是虚无类型。

    Empty Type

    示例中
    data Sum
    该类型没有实体,是 Empty Type。

    MultiParamTypeClasses

    {-# LANGUAGE MultiParamTypeClasses #-}
    允许类型类的定义中包含一个以上的参数。
    示例中
    class Monoid b a
    的类型签名中含有两个类型参数 b 和 a。

    FlexibleInstances

    {-# LANGUAGE FlexibleInstances #-}
    允许类型实例的类型签名中包含类型别名或嵌套类型。
    示例中
    instance Monoid b [a]
    的类型签名中含有嵌套类型 [a]。

    ExplicitForAll

    {-# LANGUAGE ExplicitForAll #-}
    允许显式使用 forall

    ScopedTypeVariables

    {-# LANGUAGE ScopedTypeVariables #-}
    允许 forall 所引进的类型变量用作类型修饰。
    示例中
    fold :: forall b a . Monoid b a => [a] -> a
    的类型签名中 forall 所声明的两个类型参数 b 和 a。

    TypeApplications

    {-# LANGUAGE TypeApplications #-}
    允许使用类型应用程序(Type Application)的语法。
    使用 TypeApplications 可以将某个多态函数应用到某个具体类型上(该类型前需要加上 @)
    相当于在别的语言中调用泛型函数时指定类型参数。

    Prelude> :set -XTypeApplications
    Prelude> show (read @Int "5")
    "5"
    

    示例中
    sum = fold @Sum
    将 fold 函数的类型变量 b 指定为类型实例 Sum

    Visible type applications

  • 相关阅读:
    Java工作中常用到的工具
    得到区块链直播记录
    如何高效的解决问题
    pgsql数据库应用两点注意
    flask如何使模板返回大文件,又不消耗大量内存
    python内存诊断
    pycharm整体缩进的快捷键
    gdb生成的core文件位置
    gdb源码安装,指定使用的python版本
    gdb源码安装过程中的问题:no termcap library found
  • 原文地址:https://www.cnblogs.com/zwvista/p/12880435.html
Copyright © 2011-2022 走看看