Jok*_*ven 0 haskell functional-programming list
我是Haskell的新手,我正在尝试创建一个名为Human的自定义数据类型列表.Human的定义如下:data Human = Human(String),因此Human本质上是一个String.人类的定义是高或短(S或T),女性或男性(F或M),以及他们是成人还是儿童(A或C).
我试过编写一个函数,它基本上给了我一个上面值的每个可能组合的人员列表,即= ["SFA","SFC",TMC"...].这就是我想出来的远:
func :: ([Human], state)
func = (x, state_) where
remainingHumans = [[height, sex, age] | height <- ["T", "S"], sex <- ["M", "F"], age <- ["A", "C"]]
allHumans = [Person(human) | human <- subsequences remainingHumans, length human == 3]
x = head allHumans
state _ = allHumans \\ [x]
Run Code Online (Sandbox Code Playgroud)
我尝试编译程序时收到此错误:
Couldn't match type ‘[[Char]]’ with ‘Char’
Expected type: String
Actual type: [[[Char]]]
Run Code Online (Sandbox Code Playgroud)
由于我很新,我也很失落如何继续.任何帮助或提示都会受到极大的关注
Wil*_*sem 11
我想既然height,sex并且age基本上是字符,它可能是更好的呈现这些为字符.所以我们可以写height <- ['T', 'S']代替height <- ["T", "S"],甚至更短height <- "TS".如果我们构造一个Strings 列表,我们不构造一个String,但是 - 好 - 一个Strings 的列表.
由于您可以访问这些字符,因此可以构造三个字符的列表height,sex并age通过构建列表:a String只是一个类型别名[Char].
我们还可以进行其他改进.既然我们构造了三个元素的列表,长度总是三,所以我们并不需要检查的过程中这以后,我们可以使HumanS(我想你混淆Person和Human直接).
您state在签名中指定,但这是一个类型变量.这意味着它可以是任何东西.然而,这显然是Humans 的列表,所以你需要将sgianture更改为(Human, [Human]).
最后,我们不必构造一个head获取第一个元素,但可以使用模式匹配,也不必从列表中删除该元素:因为所有元素都是唯一的,剩下的元素都在尾部(而不是其他元素)元素在尾巴中):
func :: ([Human], [Human])
func = (x, state_) where
(x:state_) = [Human [height, sex, age] | height <- "TS", sex <- "MF", age <- "AC"]Run Code Online (Sandbox Code Playgroud)
可能的改进
我认为如果你定义一个Humanas ,建模可能会更好:
data Human = Human Height Sex Age
data Height = Tall | Small
data Sex = Male | Female
data Age = Adult | Child
Run Code Online (Sandbox Code Playgroud)
通过这样做,您可以限制可以通过设计构建的人数.实际上,现在可能有一个函数包含一个小错误,并产生Human "ABC"(字符不在"域"中),或Human "TM"(字符太少)或Human "AMT"(交换顺序).这可能会在以后的过程中导致很多麻烦.通过在类型中指定域等,函数根本无法生成这样的值(编译器会引发错误).因此它为您提供了"更强大的保证",即功能正常运行.当然,该函数仍然可能包含语义错误.
此外,通过定义单独的参数,您还强制每个人都具有这三个属性,并且构造函数现在是curry.
这也将使得创建人先易后难的过程(<$>) :: f (a -> b) -> f a -> f b和(<*>) :: f (a -> b) -> f a -> f b功能:
Human <$> [Tall, Small] <*> [Male, Female] <*> [Adult, Child]
Run Code Online (Sandbox Code Playgroud)