我目前正试图想出一种方法来编写电话簿"。 (这是大学的一项任务,所以我很感激提示而不是完整的解决方案)
我创建了一个函数,使用户可以按如下方式写入多个名称:
(必须解决这个问题,因为我们必须使用type TelephoneBook = String -> String
)
(enterName "Peter" "4232" (enterName "Alice" "23213" emptyBook)) ""
然后返回Peter
。
现在我应该能够访问这些数据并搜索名称,然后检索一个数字。 我目前的想法如下:
searchFkt :: String -> TelephoneBook -> String
searchFkt a b
| (a == book "") = a --Iam fully aware that this doesn't work
| otherwise = "not found"
我知道第二部分并不像那样工作(searchFkt :: String -> TelephoneBook -> String
也是如此),但我不知道如何实现这一点,我真的需要帮助,因为我一直在寻找通过书籍,并试图围绕如何解决这个问题几个小时。
提前致谢
Ps:我想了解它是如何工作的,而不仅仅是一个解决方案,所以也许对阅读内容的参考也会有所帮助:)
答案 0 :(得分:2)
这本身并不是一个答案,而是为了澄清你的作业,无论是为了你还是为了其他人试图阅读你的问题。
您的作业的最终目标似乎是使用功能实现电话簿;一个硬编码的例子可能是
type TelephoneBook = String -> String
myPhoneBook :: TelephoneBook
myPhoneBook "Peter" = "4232"
myPhoneBook "Alice" = "23213"
请注意,这只是部分功能;对于绝大多数可能的名称,它根本没有定义。
这种方法的一个问题是它不允许真正空的电话簿,因为你无法定义一个实际上没有任何的功能。因此,我们将使用“空白”书替换它,该书会为电话簿中尚未包含的任何名称返回默认值:
-- Not ideal, but it's the best we can do given the constraints
-- imposed by the given type.
empty :: TelephoneBook
empty _ = "not found"
您的目标是编写一个功能enterName
,其中包含姓名,电话号码和现有电话簿,并返回与旧电话簿相同的新电话簿一个,但有一个新条目(覆盖任何以前具有相同名称的条目。即,
empty "Peter" == "not found"
(enterName "Peter" "1234" empty) "Peter" == "1234"
(enterName "Peter" "1234" empty) "Bob" == "not found"
(enterName "Bob" "9876" (enterName "Peter" "1234" empty)) "Bob" == "9876"
您的enterName
函数的类型为String -> String -> TelephoneBook -> TelephoneBook
,这意味着它需要三个参数,并且它需要实际上对所有三个参数执行某些操作。
enterName :: String -> String -> TelephoneBook -> TelephoneBook
enterName name number phonebook = ...
同样,您的searchFkt :: String -> TelephoneBook -> String
函数会使用名称和电话簿,并在书中返回与该名称相关联的数字。
searchFkt :: String -> TelephoneBook -> String
searchFkt name book = ...
鉴于上面TelephoneBook
的定义及其使用示例,应该明白如何实施searchFkt
。
答案 1 :(得分:1)
鉴于你说Telephonebook
是一个类型别名String -> String
,我想你想要编写一个将名字映射到电话号码的功能。因此,如果您从书中查找"Peter"
,则会返回"4232"
。
现在,如果您要搜索名称,您只需调用电话簿上的查询即可。所以searchFkt
看起来像是:
searchFkt :: String -> Telephonebook -> String
searchFkt query book = book query
然而,根据您的评论,我认为您在enterName
计划中犯了错误。 Here你说你实现了它:
putName :: String -> String -> Telephonebook -> Telephonebook
putName name number oldbook = \x -> number
(我冒昧地重命名a
,b
和c
。)。如您所见,name
和oldbook
甚至没有在表达式的右侧提及。结果Haskell忘记了这些:因此意味着name
,oldbook
也不会在新书的构建中发挥作用。
更好的方法是将其实现为:
putName :: String -> String -> Phonebook -> Phonebook
putName name number oldbook = newbook
where newbook query | query == name = number
| otherwise = oldbook query
换句话说,您构造了一个新函数newbook
,它将query
(您应该解析的名称)作为输入。如果query
等于给定的新name
,则返回number
;否则它会要求oldbook
进一步处理它。
最后,我认为将电话簿实现为函数String -> String
并不是一个好主意,因为下一个任务可能是实现反向查找操作,在这种情况下您将丢失。最好将它实现为像[(String,String)]
这样的元组列表(当然,哈希映射等会更理想)。