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 = ...