ãã¡ã³ãã åã§å ç¢ãªãœãããŠã§ã¢éçºãå®çŸããŸãããããã®å æ¬çãªã¬ã€ãã§ã¯ãã³ã³ãã€ã«æãã©ã³ã匷å¶ãã¿ãŒã³ããã®å©ç¹ããŠãŒã¹ã±ãŒã¹ãããã³ã°ããŒãã«éçºè åãã®å®è·µçãªå®è£ ãæ¢ããŸãã
ãã¡ã³ãã åïŒå ç¢ãªãœãããŠã§ã¢ã®ããã®ã³ã³ãã€ã«æãã©ã³ã匷å¶
ä¿¡é Œæ§ãé«ãä¿å®ãããããœãããŠã§ã¢ãæ§ç¯ãããšããçµ¶ãéãªã远æ±ã®äžã§ãéçºè ã¯ããšã©ãŒãæ¬çªç°å¢ã«å°éããåã«é²ãæ¹æ³ãåžžã«æš¡çŽ¢ããŠããŸããå®è¡æãã§ãã¯ã¯é²åŸ¡å±€ãæäŸããŸããã究極ã®ç®æšã¯ãå¯èœãªéãæ©æã«ãã°ãæãããããšã§ããã³ã³ãã€ã«æã®å®å šæ§ã¯ããã®ç®æšéæã®ãèæ¯ãã§ãããããã«å€§ããè²¢ç®ãããšã¬ã¬ã³ãã§åŒ·åãªãã¿ãŒã³ã®äžã€ãããã¡ã³ãã åã®äœ¿çšã§ãã
ãã®ã¬ã€ãã§ã¯ããã¡ã³ãã åã®äžçã«æ·±ãèžã¿èŸŒã¿ããããäœã§ãããããªãã³ã³ãã€ã«æãã©ã³ã匷å¶ã«ãšã£ãŠéåžžã«éèŠã§ãããããããŠããŸããŸãªããã°ã©ãã³ã°èšèªã§ã©ã®ããã«å®è£ ã§ããããæ¢ããŸãããã®å©ç¹ãå®çšçãªã¢ããªã±ãŒã·ã§ã³ãæœåšçãªèœãšã穎ã«ã€ããŠãããããèæ¯ãæã€éçºè åãã«ã°ããŒãã«ãªèŠç¹ãæäŸããŸãã
ãã¡ã³ãã åãšã¯ïŒ
ãã¡ã³ãã åã¯ããã®æ žå¿ã«ãããŠãåæ å ±ã®ã¿ã«äœ¿çšãããå®è¡æã®è¡šçŸãå°å ¥ããªãåã§ããèšãæããã°ããã¡ã³ãã åãã©ã¡ãŒã¿ãŒã¯ãéåžžããªããžã§ã¯ãã®å®éã®ããŒã¿æ§é ãå€ã«ã¯åœ±é¿ããŸãããåã·ã°ããã£ã«ããããã®ååšã¯ãç¹å®ã®å¶çŽã匷å¶ããããããã§ãªããã°åäžã®åºç€ãšãªãåã«ç°ãªãæå³ãä»äžããããã圹å²ãæãããŸãã
ããã¯ãåºç€ãšãªããã³ã³ãããã倿Žããããšãªããã³ã³ãã€ã«æã«åã«ãã©ãã«ããŸãã¯ããã©ã³ããã远å ãããã®ãšèããŠãã ããããã®ã©ãã«ã¯ãç°ãªãããã©ã³ãããæã€å€ãäžé©åã«æ··ããåããªãããã«ãããšãå®è¡æã«ã¯æ ¹æ¬çã«åãåã§ãã£ãŠããã³ã³ãã€ã©ãã¬ã€ãããŸãã
ããã¡ã³ãã ããªåŽé¢
ããã¡ã³ãã ããšããåç§°ã¯ããããã®åãã©ã¡ãŒã¿ãŒãå®è¡æã«ã¯ãèŠããªãããšããäºå®ããæ¥ãŠããŸããã³ãŒããã³ã³ãã€ã«ããããšããã¡ã³ãã åãã©ã¡ãŒã¿ãŒèªäœã¯æ¶æ» ããŸããããã¯ã³ã³ãã€ã«ãã§ãŒãºäžã«åå®å šæ§ã匷å¶ãããšããç®çãæãããæçµçãªå®è¡ãã¡ã€ã«ããæ¶å»ãããŠããŸãããã®æ¶å»ãããã®æå¹æ§ãšå¹çæ§ã®éµãšãªããŸãã
ãªããã¡ã³ãã åã䜿çšããã®ãïŒã³ã³ãã€ã«æãã©ã³ã匷å¶ã®å
ãã¡ã³ãã åãæ¡çšããäž»ãªåæ©ã¯ãã³ã³ãã€ã«æãã©ã³ã匷å¶ã§ããããã¯ãç¹å®ã®ããã©ã³ããã®å€ãããã®ç¹å®ã®ãã©ã³ããæåŸ ãããã³ã³ããã¹ãã§ã®ã¿äœ¿çšãããããšãä¿èšŒããããšã§ãè«ççãšã©ãŒãé²ãããšãæå³ããŸãã
ç°¡åãªã·ããªãªãèããŠã¿ãŸãããïŒééç䟡å€ã®åŠçã`Decimal` åããããšããŸãããã¡ã³ãã åããªããšã誀ã£ãŠ`USD`éé¡ã`EUR`éé¡ãšæ··ããŠããŸãã誀ã£ãèšç®ã誀ã£ãããŒã¿ã«ã€ãªããå¯èœæ§ããããŸãããã¡ã³ãã åã䜿çšãããšã`Decimal`åã«å¯ŸããŠ`USD`ã`EUR`ã®ãããªåå¥ã®ããã©ã³ãããäœæã§ããã³ã³ãã€ã©ã¯æç€ºçãªå€æãªãã«`USD`ã®Decimalã`EUR`ã®Decimalã«è¿œå ããããšãé²ããŸãã
ãã®ã³ã³ãã€ã«æåŒ·å¶ã®å©ç¹ã¯å€å²ã«ããããŸãã
- å®è¡æãšã©ãŒã®åæžïŒ å®è¡æã«è¡šé¢åããã¯ãã ã£ãå€ãã®ãã°ãã³ã³ãã€ã«äžã«ææãããããå®å®ãããœãããŠã§ã¢ã«ã€ãªãããŸãã
- ã³ãŒãã®æçããšæå³ã®åäžïŒ åã·ã°ããã£ããã衚çŸè±ãã«ãªããå€ã®æå³ãããçšéãæç¢ºã«ç€ºããŸããããã«ãããä»ã®éçºè ïŒãããŠæªæ¥ã®èªåïŒïŒã«ãšã£ãŠã³ãŒããçè§£ãããããªããŸãã
- ä¿å®æ§ã®åäžïŒ ã·ã¹ãã ãæé·ããã«ã€ããŠãããŒã¿ãããŒãå¶çŽã远跡ããã®ãé£ãããªããŸãããã¡ã³ãã åã¯ããããã®äžå€éãç¶æããããã®å ç¢ãªã¡ã«ããºã ãæäŸããŸãã
- ãã匷åãªä¿èšŒïŒ å®è¡æãã§ãã¯ã ãã§ã¯éæã§ããªãã¬ãã«ã®å®å šæ§ãæäŸããŸããå®è¡æãã§ãã¯ã¯è¿åãããããå¿ãããããããå¯èœæ§ããããŸãã
- ãªãã¡ã¯ã¿ãªã³ã°ã®ä¿é²ïŒ ãã峿 Œãªã³ã³ãã€ã«æãã§ãã¯ã«ããããªãã¡ã¯ã¿ãªã³ã°ã®ã³ãŒãã¯ãªã¹ã¯ãå°ãªããªãã倿Žã«ãã£ãŠå°å ¥ãããåé¢é£ã®äžæŽåãã³ã³ãã€ã©ããã©ã°ä»ãããŸãã
èšèªãè¶ ããäŸç€º
ãã¡ã³ãã åã¯ãåäžã®ããã°ã©ãã³ã°ãã©ãã€ã ãèšèªã«éå®ãããŸããã匷åãªéçåä»ããæã€èšèªãç¹ã«GenericsãType ClassesããµããŒãããèšèªã§å®è£ ã§ããŸãã
1. HaskellïŒåã¬ãã«ããã°ã©ãã³ã°ã®ãã€ãªãã¢
Haskellã¯ããã®æŽç·Žãããåã·ã¹ãã ã«ããããã¡ã³ãã åã«ãšã£ãŠèªç¶ãªç°å¢ãæäŸããŸãããããã¯ãã°ãã°ãDataKindsãããGADTãïŒGeneralized Algebraic Data TypesïŒãšåŒã°ããææ³ã䜿çšããŠå®è£ ãããŸãã
äŸïŒåäœã®è¡šçŸ
ã©ã¡ããæçµçã«ã¯æµ®åå°æ°ç¹æ°ã§ããã«ãããããããã¡ãŒãã«ãšãã£ãŒããåºå¥ããããšããŸãããã
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
-- Define a kind (a type-level "type") to represent units
data Unit = Meters | Feet
-- Define a GADT for our phantom type
data MeterOrFeet (u :: Unit) where
Length :: Double -> MeterOrFeet u
-- Type synonyms for clarity
type Meters = MeterOrFeet 'Meters
type Feet = MeterOrFeet 'Feet
-- Function that expects meters
addMeters :: Meters -> Meters -> Meters
addMeters (Length l1) (Length l2) = Length (l1 + l2)
-- Function that accepts any length but returns meters
convertAndAdd :: MeterOrFeet u -> MeterOrFeet v -> Meters
convertAndAdd (Length l1) (Length l2) = Length (l1 + l2) -- Simplified for example, real conversion logic needed
main :: IO ()
main = do
let fiveMeters = Length 5.0 :: Meters
let tenMeters = Length 10.0 :: Meters
let resultMeters = addMeters fiveMeters tenMeters
print resultMeters
-- The following line would cause a compile-time error:
-- let fiveFeet = Length 5.0 :: Feet
-- let mixedResult = addMeters fiveMeters fiveFeet
ãã®Haskellã®äŸã§ã¯ã`Unit`ã¯ã«ã€ã³ãã§ããã`Meters`ãš`Feet`ã¯åã¬ãã«ã®è¡šçŸã§ãã`MeterOrFeet` GADTã¯ãã¡ã³ãã åãã©ã¡ãŒã¿ãŒ`u`ïŒ`Unit`ã«ã€ã³ãïŒã䜿çšããŸããã³ã³ãã€ã©ã¯ã`addMeters`ã`Meters`åã®åŒæ°ã®ã¿ãåãå ¥ããããšãä¿èšŒããŸãã`Feet`åã®å€ãæž¡ãããšãããšãã³ã³ãã€ã«æã«åãšã©ãŒãçºçããŸãã
2. ScalaïŒGenericsãšOpaque Typesã®æŽ»çš
Scalaã®åŒ·åãªåã·ã¹ãã ãç¹ã«Genericsã®ãµããŒããšãScala 3ã§å°å ¥ããã opaque types ã®ãããªæè¿ã®æ©èœã¯ããã¡ã³ãã åã®å®è£ ã«é©ããŠããŸãã
äŸïŒãŠãŒã¶ãŒããŒã«ã®è¡šçŸ
ã©ã¡ããåçŽãª`UserId`ïŒ`Int`ïŒã§è¡šãããã«ããããããã`Admin`ãŠãŒã¶ãŒãš`Guest`ãŠãŒã¶ãŒãåºå¥ããããšãæ³åããŠãã ããã
// Using Scala 3's opaque types for cleaner phantom types
object PhantomTypes {
// Phantom type tag for Admin role
trait AdminRoleTag
type Admin = UserId with AdminRoleTag
// Phantom type tag for Guest role
trait GuestRoleTag
type Guest = UserId with GuestRoleTag
// The underlying type, which is just an Int
opaque type UserId = Int
// Helper to create a UserId
def apply(id: Int): UserId = id
// Extension methods to create branded types
extension (uid: UserId) {
def asAdmin: Admin = uid.asInstanceOf[Admin]
def asGuest: Guest = uid.asInstanceOf[Guest]
}
// Function requiring an Admin
def deleteUser(adminId: Admin, userIdToDelete: UserId): Unit = {
println(s"Admin $adminId deleting user $userIdToDelete")
}
// Function for general users
def viewProfile(userId: UserId): Unit = {
println(s"Viewing profile for user $userId")
}
def main(args: Array[String]): Unit = {
val regularUserId = UserId(123)
val adminUserId = UserId(1)
viewProfile(regularUserId)
viewProfile(adminUserId.asInstanceOf[UserId]) // Must cast back to UserId for general functions
val adminUser: Admin = adminUserId.asAdmin
deleteUser(adminUser, regularUserId)
// The following line would cause a compile-time error:
// deleteUser(regularUserId.asInstanceOf[Admin], regularUserId)
// deleteUser(regularUserId, regularUserId) // Incorrect types passed
}
}
ãã®Scala 3ã®äŸã§ã¯ã`AdminRoleTag`ãš`GuestRoleTag`ã¯ããŒã«ãŒãã¬ã€ãã§ãã`UserId`㯠opaque type ã§ãã亀差åïŒ`UserId with AdminRoleTag`ïŒã䜿çšããŠãã©ã³ãåãããåãäœæããŸããã³ã³ãã€ã©ã¯ã`deleteUser`ã`Admin`åãç¹ã«èŠæ±ããããšã匷å¶ããŸããéåžžã®`UserId`ã`Guest`ãæž¡ãããšãããšãåãšã©ãŒãçºçããŸãã
3. TypeScriptïŒå ¬ç§°åãšãã¥ã¬ãŒã·ã§ã³ã®æŽ»çš
TypeScriptã¯ä»ã®èšèªã®ãããªçã®å ¬ç§°åãæã£ãŠããŸãããããã©ã³ãåã`unique symbols`ãæŽ»çšããããšã§ããã¡ã³ãã åã广çã«ã·ãã¥ã¬ãŒãã§ããŸãã
äŸïŒç°ãªãé貚éé¡ã®è¡šçŸ
// Define branded types for different currencies
// We use opaque interfaces to ensure the branding is not erased
// Brand for US Dollars
interface USD {}
// Brand for Euros
interface EUR {}
type UsdAmount = number & { __brand: USD };
type EurAmount = number & { __brand: EUR };
// Helper functions to create branded amounts
function createUsdAmount(amount: number): UsdAmount {
return amount as UsdAmount;
}
function createEurAmount(amount: number): EurAmount {
return amount as EurAmount;
}
// Function that adds two USD amounts
function addUsd(a: UsdAmount, b: UsdAmount): UsdAmount {
return createUsdAmount(a + b);
}
// Function that adds two EUR amounts
function addEur(a: EurAmount, b: EurAmount): EurAmount {
return createEurAmount(a + b);
}
// Function that converts EUR to USD (hypothetical rate)
function eurToUsd(amount: EurAmount, rate: number = 1.1): UsdAmount {
return createUsdAmount(amount * rate);
}
// --- Usage ---
const salaryUsd = createUsdAmount(50000);
const bonusUsd = createUsdAmount(5000);
const totalSalaryUsd = addUsd(salaryUsd, bonusUsd);
console.log(`Total Salary (USD): ${totalSalaryUsd}`);
const rentEur = createEurAmount(1500);
const utilitiesEur = createEurAmount(200);
const totalRentEur = addEur(rentEur, utilitiesEur);
console.log(`Total Utilities (EUR): ${totalRentEur}`);
// Example of conversion and addition
const eurConvertedToUsd = eurToUsd(totalRentEur);
const finalUsdAmount = addUsd(totalSalaryUsd, eurConvertedToUsd);
console.log(`Final Amount in USD: ${finalUsdAmount}`);
// The following lines would cause compile-time errors:
// Error: Argument of type 'UsdAmount' is not assignable to parameter of type 'EurAmount'.
// const invalidAdditionEur = addEur(salaryUsd as any, rentEur);
// Error: Argument of type 'EurAmount' is not assignable to parameter of type 'UsdAmount'.
// const invalidAdditionUsd = addUsd(rentEur as any, bonusUsd);
// Error: Argument of type 'number' is not assignable to parameter of type 'UsdAmount'.
// const directNumberUsd = addUsd(1000, bonusUsd);
ãã®TypeScriptã®äŸã§ã¯ã`UsdAmount`ãš`EurAmount`ã¯ãã©ã³ãåã§ãããããã¯åºæ¬çã«`number`åã§ãããã³ã³ãã€ã©ã远跡ãããè€è£œäžå¯èœãªè¿œå ããããã£ïŒ`__brand`ïŒãæã¡ãŸããããã«ãããå®è¡æã«ã¯ã©ã¡ããåãªãæ°å€ã§ããã«ãããããããç°ãªãæŠå¿µïŒUSDãšEURïŒã衚ãåå¥ã®åãã³ã³ãã€ã«æã«äœæã§ããŸããåã·ã¹ãã ã¯ãããããçŽæ¥æ··åšãããããšãé²ããŸãã
4. RustïŒPhantomDataã®æŽ»çš
Rustã¯ããã®æšæºã©ã€ãã©ãªã«`PhantomData`æ§é äœãæäŸããŠãããããã¯ãã®ç®çã®ããã«ç¹å¥ã«èšèšãããŠããŸãã
äŸïŒãŠãŒã¶ãŒæš©éã®è¡šçŸ
use std::marker::PhantomData;
// Phantom type for Read-Only permission
struct ReadOnlyTag;
// Phantom type for Read-Write permission
struct ReadWriteTag;
// A generic 'User' struct that holds some data
struct User {
id: u32,
name: String,
}
// The phantom type struct itself
struct UserWithPermission<P> {
user: User,
_permission: PhantomData<P> // PhantomData to tie the type parameter P
}
impl<P> UserWithPermission<P> {
// Constructor for a generic user with a permission tag
fn new(user: User) -> Self {
UserWithPermission { user, _permission: PhantomData }
}
}
// Implement methods specific to ReadOnly users
impl UserWithPermission<ReadOnlyTag> {
fn read_user_info(&self) {
println!("Read-only access: User ID: {}, Name: {}", self.user.id, self.user.name);
}
}
// Implement methods specific to ReadWrite users
impl UserWithPermission<ReadWriteTag> {
fn write_user_info(&self) {
println!("Read-write access: Modifying user ID: {}, Name: {}", self.user.id, self.user.name);
// In a real scenario, you'd modify self.user here
}
}
fn main() {
let base_user = User { id: 1, name: "Alice".to_string() };
// Create a read-only user
let read_only_user = UserWithPermission::new(base_user); // Type inferred as UserWithPermission<ReadOnlyTag>
// Attempting to write will fail at compile time
// read_only_user.write_user_info(); // Error: no method named `write_user_info`...
read_only_user.read_user_info();
let another_base_user = User { id: 2, name: "Bob".to_string() };
// Create a read-write user
let read_write_user = UserWithPermission::new(another_base_user);
read_write_user.read_user_info(); // Read methods are often available if not shadowed
read_write_user.write_user_info();
// Type checking ensures we don't mix them unintentionally.
// The compiler knows that read_only_user is of type UserWithPermission<ReadOnlyTag>
// and read_write_user is of type UserWithPermission<ReadWriteTag>.
}
ãã®Rustã®äŸã§ã¯ã`ReadOnlyTag`ãš`ReadWriteTag`ã¯åçŽãªæ§é äœããŒã«ãŒã§ãã`UserWithPermission<P>`å ã®`PhantomData<P>`ã¯ã`P`ãæŠå¿µçã«æ§é äœãäŸåããåãã©ã¡ãŒã¿ãŒã§ããããšãRustã³ã³ãã€ã©ã«äŒããŸããã`P`åã®å®éã®ããŒã¿ãæ ŒçŽããããšã¯ãããŸãããããã«ãããRustã®åã·ã¹ãã ã¯`UserWithPermission<ReadOnlyTag>`ãš`UserWithPermission<ReadWriteTag>`ãåºå¥ã§ããç¹å®ã®æš©éãæã€ãŠãŒã¶ãŒã«å¯ŸããŠã®ã¿åŒã³åºãå¯èœãªã¡ãœãããå®çŸ©ã§ããããã«ãªããŸãã
ãã¡ã³ãã åã®äžè¬çãªãŠãŒã¹ã±ãŒã¹
åçŽãªäŸãè¶ ããŠããã¡ã³ãã åã¯ããŸããŸãªè€éãªã·ããªãªã§å¿çšãããŸãã
- ç¶æ ã®è¡šçŸïŒ ç°ãªãåãç°ãªãç¶æ ã衚ãæéç¶æ æ©æ¢°ã®ã¢ããªã³ã°ïŒäŸïŒ`UnauthenticatedUser`ã`AuthenticatedUser`ã`AdminUser`ïŒã
- åå®å šãªåäœã®æž¬å®ïŒ 瀺ãããŠããããã«ã次å çã«äžæ£ç¢ºãªèšç®ãé¿ããããã«ãç§åŠèšç®ãå·¥åŠãéèã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠéåžžã«éèŠã§ãã
- ãããã³ã«ã®ãšã³ã³ãŒãïŒ ç¹å®ã®ãããã¯ãŒã¯ãããã³ã«ãŸãã¯ã¡ãã»ãŒãžåœ¢åŒã«æºæ ããããŒã¿ãæ£ããåŠçãããå¥ã®ããŒã¿ãšæ··åãããªãããã«ããŸãã
- ã¡ã¢ãªå®å šæ§ãšãªãœãŒã¹ç®¡çïŒ è§£æŸããŠãå®å šãªããŒã¿ãšããã§ãªãããŒã¿ãåºå¥ããããå€éšãªãœãŒã¹ãžã®ç°ãªãçš®é¡ã®ãã³ãã«ãåºå¥ãããããŸãã
- 忣ã·ã¹ãã ïŒ ç¹å®ã®ããŒããŸãã¯å°åã察象ãšããããŒã¿ãŸãã¯ã¡ãã»ãŒãžãããŒã¯ããŸãã
- ãã¡ã€ã³åºæèšèªïŒDSLïŒã®å®è£ ïŒ åã䜿çšããŠæå¹ãªæäœã·ãŒã±ã³ã¹ã匷å¶ããããšã«ããããã衚çŸè±ãã§å®å šãªå éšDSLãäœæããŸãã
ãã¡ã³ãã åãå®è£ ããäžã§ã®èæ ®äºé
ãã¡ã³ãã åãå®è£ ããéã«ã¯ã次ã®ç¹ãèæ ®ããŠãã ããã
- èšèªãµããŒãïŒ äœ¿çšããèšèªããGenericsãåãšã€ãªã¢ã¹ããŸãã¯åã¬ãã«ã®åºå¥ãå¯èœã«ããæ©èœïŒHaskellã®GADTãScalaã®opaque typesãTypeScriptã®ãã©ã³ãåãªã©ïŒãå ç¢ã«ãµããŒãããŠããããšã確èªããŠãã ããã
- ã¿ã°ã®æç¢ºãïŒ ãã¡ã³ãã åãåºå¥ããããã«äœ¿çšããããã¿ã°ããŸãã¯ãããŒã«ãŒãã¯ãæç¢ºã§æå³ã®ãããã®ã§ããã¹ãã§ãã
- ãã«ããŒé¢æ°/ã³ã³ã¹ãã©ã¯ã¿ïŒ ãã©ã³ãåãäœæããå¿ èŠã«å¿ããŠãããã倿ããããã®æç¢ºã§å®å šãªæ¹æ³ãæäŸããŸããããã¯äœ¿ããããã«ãšã£ãŠéåžžã«éèŠã§ãã
- æ¶å»ã¡ã«ããºã ïŒ äœ¿çšããèšèªãåæ¶å»ãã©ã®ããã«åŠçããããçè§£ããŠãã ããããã¡ã³ãã åã¯ã³ã³ãã€ã«æãã§ãã¯ã«äŸåããéåžžã¯å®è¡æã«æ¶å»ãããŸãã
- ãªãŒããŒãããïŒ ãã¡ã³ãã åèªäœã«ã¯å®è¡æã®ãªãŒããŒãããã¯ãããŸããããè£å©çãªã³ãŒãïŒãã«ããŒé¢æ°ãããè€éãªåå®çŸ©ãªã©ïŒã¯å€å°ã®è€éããå°å ¥ããå¯èœæ§ããããŸããããããããã¯éåžžãåŸãããå®å šæ§ã®ããã«äŸ¡å€ã®ãããã¬ãŒããªãã§ãã
- ããŒã«ãšIDEã®ãµããŒãïŒ åªããIDEãµããŒãã¯ããªãŒãã³ã³ããªãŒããæç¢ºãªãšã©ãŒã¡ãã»ãŒãžããã¡ã³ãã åã«å¯ŸããŠæäŸããããšã§ãéçºè ã®äœéšãå€§å¹ ã«åäžãããããšãã§ããŸãã
æœåšçãªèœãšã穎ãšåé¿ãã¹ãã±ãŒã¹
ãã¡ã³ãã åã¯åŒ·åã§ãããäžèœè¬ã§ã¯ãªããããèªäœã®èª²é¡ãå°å ¥ããå¯èœæ§ããããŸãã
- è€éãã®å¢å ïŒ åçŽãªã¢ããªã±ãŒã·ã§ã³ã®å Žåããã¡ã³ãã åãå°å ¥ãããšããªãŒããŒãã«ãšãªããã³ãŒãããŒã¹ã«äžå¿ èŠãªè€éãã远å ããå¯èœæ§ããããŸãã
- åé·æ§ïŒ ãã©ã³ãåãäœæããã³ç®¡çãããšãç¹ã«ãã«ããŒé¢æ°ãæ¡åŒµæ©èœã§ç®¡çãããŠããªãå Žåãã³ãŒããåé·ã«ãªãããšããããŸãã
- åŠç¿æ²ç·ïŒ ãããã®é«åºŠãªåã·ã¹ãã æ©èœã«äžæ £ããªéçºè ã¯ãæåã¯æ··ä¹±ãããããããŸãããé©åãªããã¥ã¡ã³ããšãªã³ããŒãã£ã³ã°ãäžå¯æ¬ ã§ãã
- åã·ã¹ãã ã®å¶éïŒ åã·ã¹ãã ãããŸãæŽç·ŽãããŠããªãèšèªã§ã¯ããã¡ã³ãã åãã·ãã¥ã¬ãŒãããã®ãé¢åã§ãã£ãããåãã¬ãã«ã®å®å šæ§ãæäŸã§ããªãã£ããããå ŽåããããŸãã
- å¶çºçãªæ¶å»ïŒ ç¹ã«æé»çãªå倿ãå³å¯ã§ãªãåãã§ãã¯ãæã€èšèªã§æ³šææ·±ãå®è£ ãããŠããªãå Žåãããã©ã³ããã誀ã£ãŠæ¶å»ãããç®çãæãªãããå¯èœæ§ããããŸãã
泚æãå¿ èŠãªå ŽåïŒ
- ç¹å®ã®èª²é¡ã«å¯ŸããŠãè€éãã®å¢å ã®ã³ã¹ããã³ã³ãã€ã«æã®å®å šæ§ã®å©ç¹ãäžåãå Žåã
- çã®å ¬ç§°åãŸãã¯å ç¢ãªãã¡ã³ãã åãšãã¥ã¬ãŒã·ã§ã³ã®éæãå°é£ãŸãã¯ãšã©ãŒãçºçããããèšèªã®å Žåã
- å®è¡æãšã©ãŒã蚱容ããããããªãããå°èŠæš¡ãªäœ¿ãæšãŠã¹ã¯ãªããã®å Žåã
çµè«ïŒãã¡ã³ãã åã§ãœãããŠã§ã¢å質ãé«ãã
ãã¡ã³ãã åã¯ãå ç¢ã§ã³ã³ãã€ã«æã«åŒ·å¶ãããåå®å šæ§ãéæããããã®ãæŽç·ŽãããŠããªãããä¿¡ããããªãã»ã©å¹æçãªãã¿ãŒã³ã§ããåæ å ±ã®ã¿ã䜿çšããŠå€ãããã©ã³ãåãããæå³ããªãæ··åãé²ãããšã§ãéçºè ã¯å®è¡æãšã©ãŒãå€§å¹ ã«åæžããã³ãŒãã®æçããåäžãããããä¿å®ããããä¿¡é Œæ§ã®é«ãã·ã¹ãã ãæ§ç¯ã§ããŸãã
Haskellã®é«åºŠãªGADTãScalaã®opaque typesãTypeScriptã®ãã©ã³ãåãRustã®`PhantomData`ã®ãããã䜿çšããå Žåã§ããååã¯åãã§ããåã·ã¹ãã ãæŽ»çšããŠããšã©ãŒæ€åºã®éåŽåã®å€ããåŠçãããŸããããã°ããŒãã«ãªãœãããŠã§ã¢éçºããŸããŸãé«ãå質ãšä¿¡é Œæ§ã®åºæºãèŠæ±ããã«ã€ããŠããã¡ã³ãã åã®ãããªãã¿ãŒã³ãç¿åŸããããšã¯ã次äžä»£ã®å ç¢ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããšãç®æããã¹ãŠã®çå£ãªéçºè ã«ãšã£ãŠäžå¯æ¬ ãªã¹ãã«ãšãªããŸãã
ãã¡ã³ãã åããã®ç¬èªã®å®å šæ§ããããžã§ã¯ãã«ããããå Žæãæ¢ãå§ããŸããããããããçè§£ããé©çšããããšãžã®æè³ã¯ããã°ã®åæžãšã³ãŒãã®æŽåæ§ã®åäžãšããç¹ã§å€§ããªå©çãããããã§ãããã