访问一个名为

时间:2017-01-21 16:53:53

标签: function haskell lambda anonymous-function

我目前正试图想出一种方法来编写电话簿"。 (这是大学的一项任务,所以我很感激提示而不是完整的解决方案)

我创建了一个函数,使用户可以按如下方式写入多个名称:

(必须解决这个问题,因为我们必须使用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:我想了解它是如何工作的,而不仅仅是一个解决方案,所以也许对阅读内容的参考也会有所帮助:)

2 个答案:

答案 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

(我冒昧地重命名abc。)。如您所见,nameoldbook甚至没有在表达式的右侧提及。结果Haskell忘记了这些:因此意味着nameoldbook也不会在新书的构建中发挥作用。

更好的方法是将其实现为:

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)]这样的元组列表(当然,哈希映射等会更理想)。