Function 访问已调用的函数
我目前正在想办法写一本“电话簿”。(这是大学的一项任务,因此我希望得到提示而不是完整的解决方案) 我创建了一个函数,该函数允许用户按如下方式写入多个名称: (必须这样解决,因为我们必须使用Function 访问已调用的函数,function,haskell,lambda,anonymous-function,Function,Haskell,Lambda,Anonymous Function,我目前正在想办法写一本“电话簿”。(这是大学的一项任务,因此我希望得到提示而不是完整的解决方案) 我创建了一个函数,该函数允许用户按如下方式写入多个名称: (必须这样解决,因为我们必须使用type TelephoneBook=String->String) 然后返回Peter 现在我应该能够访问这些数据,搜索一个名字,然后检索一个数字。 我目前的想法如下: searchFkt :: String -> TelephoneBook -> String searchFkt a b |
type TelephoneBook=String->String
)
然后返回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:我想了解它是如何工作的,而不仅仅是有一个解决方案,所以参考一下阅读内容也会很有帮助:)如果你说
Telephonebook
是一个别名String->String
,我想你应该编写一个函数,将名字映射到电话号码上。因此,如果从书中查找“Peter”
,它将返回“4232”
现在,如果你想搜索一个名字,你所要做的就是调用电话簿上的查询。因此,searchFkt
看起来像:
searchFkt :: String -> Telephonebook -> String
searchFkt query book = book query
然而,根据您的评论,我认为您在enterName
程序中犯了一个错误。您说您将其实现为:
putName :: String -> String -> Telephonebook -> Telephonebook
putName name number oldbook = \x -> number
(我冒昧地重命名了a
、b
和c
)。如您所见,name
和oldbook
在表达式的右侧甚至没有提到。因此,哈斯克尔忘记了这些:这意味着无论是名称
,还是旧书
,都不会在新书的构建中发挥任何作用
更好的方法是通过以下方式实施:
putName :: String -> String -> Phonebook -> Phonebook
putName name number oldbook = newbook
where newbook query | query == name = number
| otherwise = oldbook query
换句话说,您构建了一个新函数newbook
,该函数将查询
(您应该解析的名称)作为输入。如果查询
等于给定的新名称
,则返回编号
;否则它会要求旧书
进一步处理它
最后,我认为将电话簿实现为函数
String->String
,不是一个好主意,因为下一个任务可能是实现反向查找操作,在这种情况下,您将丢失。最好将其实现为元组列表,如[(String,String)]
(当然,hashmaps等会更理想)。这本身并不是一个答案,而是试图澄清您的任务是什么,无论是为了您还是为了试图阅读您的问题的其他人
任务的最终目标似乎是使用函数实现电话簿;一个硬编码的例子可能是
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
为什么它会返回Peter
?enterName的类型和用途是什么?它似乎是enterName::String->String->TelephoneBook->TelephoneBook
,但是,为什么您希望将新的TelephoneBook
值应用于空字符串,以返回“Peter”
?在我们给出的控制台示例中,他们在控制台中键入上面显示的内容,它返回了名称,因此我按如下方式实现它:“putName::string->string->TelephoneBook->TelephoneBook”(这是给定的)‘putName a b c=(\x->b)’那么,putName
应该做什么?如果忽略其中两个参数,为什么需要3个参数?@fapprency:但是你完全忘记了原来的电话簿,而且所有元素都会映射到Peter这里……哇,这很快:)非常感谢,我还不知道HashMaps和querys,所以我必须对此进行研究!但你的解释有道理
searchFkt :: String -> TelephoneBook -> String
searchFkt name book = ...