• Haskell语言学习笔记(98)Smart constructors


    Smart constructors

    https://wiki.haskell.org/Smart_constructors

    智能构造器是指为了在构造过程中对构造器的参数加以限制,不提供缺省的数据构造器,而是提供特别的函数来充当构造器。
    智能构造器可分为运行期检查和编译期检查两类。

    示例

    {-# LANGUAGE FlexibleInstances #-}
    
    module Resistor (
             Resistor,       -- abstract, hiding constructors
             metalResistor1,  -- only way to build a metal resistor
             metalResistor2,  -- only way to build a metal resistor
             Resistor3,       -- abstract, hiding constructors
             resistor3,  -- only way to build a metal resistor
           ) where
    
    import Control.Exception(assert)
    
    -- runtime check
    
    data Resistor = Metal   Bands
                  | Ceramic Bands 
                    deriving Show
    
    type Bands = Int
    
    metalResistor1 :: Bands -> Resistor
    metalResistor1 n | n < 4 || n > 8 = error "Invalid number of resistor bands" 
                    | otherwise      = Metal n
    
    metalResistor2 :: Bands -> Resistor
    metalResistor2 n = assert (n >= 4 && n <= 8) $ Metal n
    
    -- compile-time check
    
    data Z   = Z
    data S a = S a
    
    class Card c where
     
    instance Card Z where
    instance (Card c) => Card (S c) where
    
    class Card size => InBounds size where
     
    instance InBounds (S (S (S (S Z)))) where                 -- four
    instance InBounds (S (S (S (S (S Z))))) where             -- five
    instance InBounds (S (S (S (S (S (S Z)))))) where         -- six
    instance InBounds (S (S (S (S (S (S (S Z))))))) where     -- seven
    instance InBounds (S (S (S (S (S (S (S (S Z)))))))) where -- eight
    
    d0  = undefined :: Z
    d3  = undefined :: S (S (S Z))
    d4  = undefined :: S (S (S (S Z)))
    d6  = undefined :: S (S (S (S (S (S Z)))))
    d8  = undefined :: S (S (S (S (S (S (S (S Z)))))))
    d10 = undefined :: S (S (S (S (S (S (S (S (S (S Z)))))))))
    
    data Resistor3 size = Resistor3 deriving Show
    
    resistor3 :: InBounds size => size -> Resistor3 size
    resistor3 _ = Resistor3
    

    运行期检查

    *Resistor> metalResistor1 4
    Metal 4
    *Resistor> metalResistor2 7
    Metal 7
    *Resistor> metalResistor1 9
    *** Exception: Invalid number of resistor bands
    CallStack (from HasCallStack):
      error, called at smart_constructors.hs:18:37 in main:Resistor
    *Resistor> metalResistor2 0
    *** Exception: Assertion failed
    CallStack (from HasCallStack):
      assert, called at smart_constructors.hs:22:20 in main:Resistor
    

    编译期检查

    *Resistor> resistor3 d0
    
    <interactive>:15:1: error:
        • No instance for (InBounds Z) arising from a use of ‘resistor3’
        • In the expression: resistor3 d0
          In an equation for ‘it’: it = resistor3 d0
    *Resistor> resistor3 d3
    
    <interactive>:16:1: error:
        • No instance for (InBounds (S (S (S Z))))
            arising from a use of ‘resistor3’
        • In the expression: resistor3 d3
          In an equation for ‘it’: it = resistor3 d3
    *Resistor> resistor3 d4
    Resistor3
    *Resistor> :t resistor3 d4
    resistor3 d4 :: Resistor3 (S (S (S (S Z))))
    *Resistor> resistor3 d6
    Resistor3
    *Resistor> resistor3 d8
    Resistor3
    *Resistor> :t resistor3 d8
    resistor3 d8 :: Resistor3 (S (S (S (S (S (S (S (S Z))))))))
    *Resistor> resistor3 d10
    
    <interactive>:22:1: error:
        • No instance for (InBounds
                             (S (S (S (S (S (S (S (S (S (S Z)))))))))))
            arising from a use of ‘resistor3’
        • In the expression: resistor3 d10
    
  • 相关阅读:
    模块
    javacript一键换肤
    ajax请求
    jquery获取元素的方法
    ajax请求里的contentType: "application/json"作用
    Underscore.js 入门-常用方法介绍
    .NET Core调用WCF的最佳实践
    证伪主义——科学与伪科学的量尺
    高效的筒仓
    此时此刻,一个项目正在走向失败
  • 原文地址:https://www.cnblogs.com/zwvista/p/12903242.html
Copyright © 2020-2023  润新知