dataに後からdata constructorを追加できますか？

[code]

    data Car = NamedCar String | NamedCarWithColorName String String
    
[/code]

上のような `data` があった時に `NamedCarWithColorNameAndEngineType String String String`
を後から追加することはできますか？




できません。  
これはHaskellの「型」が安全に使用できることを意味します。

たとえば、NamedCar -> Stringのような型を持つ関数を作成したとします。  
この関数はNamedCarとNamedCarWithColorNameの2種類の値について定義されているはずです。  
もしも、後からNamedCarWithColorNameAndEngineTypeが追加できてしまうと、  
この関数は「失敗する可能性のある関数」となってしまいます。

多くの動的型付けオブジェクト指向言語にあるような型の柔軟性はHaskellには存在しません。  
しかし、Haskellでは「より厳密な理論を背景にした」同様のコーディングができます。  
GHCの拡張機能のExistentialQuantificationを使用します。  
質問の例ならば以下のようになります。

[code]

    {-# LANGUAGE ExistentialQuantification #-}
    
    class CarClass c where
        showCar :: c -> String
    
    data Car = forall c . CarClass c => Car c
    
    instance CarClass Car where
        showCar (Car c) = showCar c
    
    data NamedCar = NamedCar String
    
    instance CarClass NamedCar where
        showCar (NamedCar n) = n
    
    data NamedCarWithColorName = NamedCarWithColorName String String
    
    instance CarClass NamedCarWithColorName where
        showCar (NamedCarWithColorName n c) = n ++ " " ++ c
    
    data NamedCarWithColorNameAndEngineType =
        NamedCarWithColorNameAndEngineType String String String
    
    instance CarClass NamedCarWithColorNameAndEngineType where
        showCar (NamedCarWithColorNameAndEngineType n c e) =
            n ++ " " ++ c ++ " " ++ e
    
    cars :: [Car]
    cars = [
        Car (NamedCar "Lexus"),
        Car (NamedCarWithColorName "Crown" "Pink"),
        Car (NamedCarWithColorNameAndEngineType "M3" "Black" "M88/3") ]
    
    main :: IO ()
    main = mapM_ (putStrLn . showCar) cars
    
[/code]




できません。  
これはHaskellの「型」が安全に使用できることを意味します。

たとえば、NamedCar -> Stringのような型を持つ関数を作成したとします。  
この関数はNamedCarとNamedCarWithColorNameの2種類の値について定義されているはずです。  
もしも、後からNamedCarWithColorNameAndEngineTypeが追加できてしまうと、  
この関数は「失敗する可能性のある関数」となってしまいます。

多くの動的型付けオブジェクト指向言語にあるような型の柔軟性はHaskellには存在しません。  
しかし、Haskellでは「より厳密な理論を背景にした」同様のコーディングができます。  
GHCの拡張機能のExistentialQuantificationを使用します。  
質問の例ならば以下のようになります。

[code]

    {-# LANGUAGE ExistentialQuantification #-}
    
    class CarClass c where
        showCar :: c -> String
    
    data Car = forall c . CarClass c => Car c
    
    instance CarClass Car where
        showCar (Car c) = showCar c
    
    data NamedCar = NamedCar String
    
    instance CarClass NamedCar where
        showCar (NamedCar n) = n
    
    data NamedCarWithColorName = NamedCarWithColorName String String
    
    instance CarClass NamedCarWithColorName where
        showCar (NamedCarWithColorName n c) = n ++ " " ++ c
    
    data NamedCarWithColorNameAndEngineType =
        NamedCarWithColorNameAndEngineType String String String
    
    instance CarClass NamedCarWithColorNameAndEngineType where
        showCar (NamedCarWithColorNameAndEngineType n c e) =
            n ++ " " ++ c ++ " " ++ e
    
    cars :: [Car]
    cars = [
        Car (NamedCar "Lexus"),
        Car (NamedCarWithColorName "Crown" "Pink"),
        Car (NamedCarWithColorNameAndEngineType "M3" "Black" "M88/3") ]
    
    main :: IO ()
    main = mapM_ (putStrLn . showCar) cars
    
[/code]

