Function 从Haskell中的函数中提取

Function 从Haskell中的函数中提取,function,haskell,integer,extract,store,Function,Haskell,Integer,Extract,Store,我有以下数据类型 type Store = Loc -> Z type Loc = Z type Z = Integer 其基本思想是,商店将一个位置映射为一个整数。每个位置都由它自己的整数标识符表示 现在在任务的其他地方我有一个存储(Loc->Z),我需要从中提取整数。所以我需要一个函数,它接收一个存储并只返回Z部分 funExtract :: Store -> Z funExtract sto = ??? 在我的生命中,我尝试过的每件事都会犯一些错误。任何帮助都将不胜感激。谢

我有以下数据类型

type Store = Loc -> Z
type Loc = Z
type Z = Integer
其基本思想是,商店将一个位置映射为一个整数。每个位置都由它自己的整数标识符表示

现在在任务的其他地方我有一个存储(Loc->Z),我需要从中提取整数。所以我需要一个函数,它接收一个存储并只返回Z部分

funExtract :: Store -> Z
funExtract sto = ???

在我的生命中,我尝试过的每件事都会犯一些错误。任何帮助都将不胜感激。谢谢

啊,是的,通过构建功能来模仿商店。这是编程语言课程中常见的一个很好的练习。您将需要两个函数,一个用于构建存储,另一个用于提取值。要构建要获取原始存储、要插入的元素和位置的存储,请执行以下操作:

type Store = Loc -> Z
type Loc = Z
type Z = Integer

extend :: Loc -> Z -> Store -> Store
extend loc val st = \look ->
  if look == loc then val else st look
extend
中,我们只定义了一个函数,如果将值传递给匹配的位置,该函数将返回该值。如果位置不匹配,则可能该位置是在原始存储中定义的,因此我们将该存储应用于查找

现在实施查找:

funExtract :: Store -> Loc -> Z
funExtract sto loc = sto loc
注意到了吗?您所建议的是将存储系统实现为一个函数,所以查找只是一个函数应用程序。由于我们不会返回
值为空的
类型,比如
可能是
类型,因此如果位置不在我们的商店中,我们需要做一些激烈的事情。让我们在空存储上查找一个错误:

emptyStore :: Store
emptyStore loc = error $ "Can not find location " ++ show loc ++ "."
下面我将在GHCi中稍微使用这个构造

*Main> let sto = extend 1 31337 (extend 0 1337 emptyStore)
*Main> sto 0
1337
*Main> sto 1
31337
*Main> sto 2
*** Exception: Can not find location 2.

存储
是一种函数类型,它获取一个位置并将其映射为一个整数。要执行任务,您应该将所有位置存储在
funExtract
中,或者使用外部存储,如
Data.Map
。下面是如何做到这一点

import qualified Data.Map as DM

type Store = Loc -> Z
type Loc   = Z
type Z     = Integer

-- First way --

funExtract :: Store
funExtract 1 = 2
funExtract 2 = 9
-- here could be more values:          --
--   for each new values a new pattern --
funExtract 108 = 17

{- This solution doesn't allow to add new locations
   at the runtime. Look at Thomas's answer to understand
   how to do this with function as a container. Or look
   at the second way:                                    -}

-- Second way --

-- To add new location, add it to locStorage using
-- functions from Data.Map.
locStorage :: DM.Map Loc Z
locStorage = DM.fromList [(1, 2), (2, 9), {- ... -} (108, 17)]

-- `funExtract` becomes just a query
funExtract' :: Store
funExtract' = (DM.!) locStorage

您的
存储
类型是
Integer->Integer
,因此
funExtract
具有类型
(Integer->Integer)->Integer
。除非传递所需的位置,否则没有要提取的
Z
部分。在
sto
参数中没有实际存储的任何内容,
Store
类型只是作为给定
Loc
的查找。您可能需要一个函数
extract::Store->Loc->Z
extract store loc=store loc
。正如其他人所说,除非提供一个位置,否则无法从存储中提取整数。有没有可能,您真正想要的不是映射,而是类似于
type Store=(Loc,Z)
?@bheklillr的东西,或者,因为
Store
是一个函数,“提取”值是函数应用程序,
extract=($)