Haskell 编译时键->;值映射

Haskell 编译时键->;值映射,haskell,Haskell,我想在编译时创建一个映射,将编译时键映射到运行时值。函数应该能够检查这些键,并在不存在所有必需键的情况下抛出编译器错误 这大概就是我想要实现的目标: class HasFirst a first :: String class HasMiddle a middle :: String class HasLast a last :: String print_full_name :: (HasFirst a, HasLast a) => a -> String ad

我想在编译时创建一个映射,将编译时键映射到运行时值。函数应该能够检查这些键,并在不存在所有必需键的情况下抛出编译器错误

这大概就是我想要实现的目标:

class HasFirst a
  first :: String

class HasMiddle a
  middle :: String

class HasLast a
  last :: String

print_full_name :: (HasFirst a, HasLast a) => a -> String

addFirst :: String -> a -> b
addFirst s x = -- ( Add a first name to x )

emptyName :: -- some empty name

x1 = addFirst "John" $ addLast "Smith" $ emptyName
x2 = addMiddle "Bob" $ addLast "Smith" $ emptyName

main = putStr $ print_full_name x1 -- Compiles
main = putStr $ print_full_name x2 -- No first name so compile error
对于那些有C++知识的人,我大致想知道什么。

我不需要上面的代码,重要的是我可以在编译时检查参数。不管机制是类还是其他什么,我都不介意


是否有一个软件包可以做到这一点,或者开发起来容易吗?

让我告诉您如何使用一种称为:

我们使用
Name
的三个类型参数来跟踪已设置的名称
printFullName
只接受名字和姓氏。尝试打印未定义的名称时出现类型错误:

*Main> printFullName $ addFirst "John" $ addLast "Smith" $ emptyName
"JohnSmith"
*Main> printFullName $ addFirst "John" $ addMiddle "Edward" $ emptyName

<interactive>:1:16:
    Couldn't match expected type `YES' against inferred type `NO'
      Expected type: Name YES YES YES
      Inferred type: Name YES YES NO
    In the second argument of `($)', namely
        `addFirst "John" $ addMiddle "Edward" $ emptyName'
    In the expression:
          printFullName $ addFirst "John" $ addMiddle "Edward" $ emptyName
*Main>printFullName$addFirst“John”$addLast“Smith”$emptyName
“约翰史密斯”
*Main>printFullName$addFirst“John”$addMiddle“Edward”$emptyName
:1:16:
无法将预期类型“YES”与推断类型“NO”匹配
预期类型:名称是是
推断类型:名称是是否
在“($)”的第二个参数中,即
`addFirst“John”$addMiddle“Edward”$emptyName'
在表达式中:
printFullName$addFirst“John”$addMiddle“Edward”$emptyName

请注意,这是一种非常粗糙的编码,但希望它能展示幻像类型的威力。

让我告诉您如何使用一种称为:

我们使用
Name
的三个类型参数来跟踪已设置的名称
printFullName
只接受名字和姓氏。尝试打印未定义的名称时出现类型错误:

*Main> printFullName $ addFirst "John" $ addLast "Smith" $ emptyName
"JohnSmith"
*Main> printFullName $ addFirst "John" $ addMiddle "Edward" $ emptyName

<interactive>:1:16:
    Couldn't match expected type `YES' against inferred type `NO'
      Expected type: Name YES YES YES
      Inferred type: Name YES YES NO
    In the second argument of `($)', namely
        `addFirst "John" $ addMiddle "Edward" $ emptyName'
    In the expression:
          printFullName $ addFirst "John" $ addMiddle "Edward" $ emptyName
*Main>printFullName$addFirst“John”$addLast“Smith”$emptyName
“约翰史密斯”
*Main>printFullName$addFirst“John”$addMiddle“Edward”$emptyName
:1:16:
无法将预期类型“YES”与推断类型“NO”匹配
预期类型:名称是是
推断类型:名称是是否
在“($)”的第二个参数中,即
`addFirst“John”$addMiddle“Edward”$emptyName'
在表达式中:
printFullName$addFirst“John”$addMiddle“Edward”$emptyName

请注意,这是一种非常粗糙的编码,但希望它能展示幻影类型的威力。

我不明白;你能举个例子说明如何使用它吗?编译时映射必须将编译时键映射到编译时值,不是吗?我误解了你的意思吗?我在我的问题中添加了一些进一步的细节…在Haskell编译时唯一真正检查的是类型系统。QED,如果您想在编译时检查某些内容,它必须是一个类型。听起来你想要的是一个包含所有合法值的枚举类型,但我真的不知道;你能举个例子说明如何使用它吗?编译时映射必须将编译时键映射到编译时值,不是吗?我误解了你的意思吗?我在我的问题中添加了一些进一步的细节…在Haskell编译时唯一真正检查的是类型系统。QED,如果您想在编译时检查某些内容,它必须是一个类型。听起来你想要的是一个包含所有合法值的枚举类型,但我真的不知道。