如何从函数图像构造函数?Haskell中graphOf逆函数实现问询
从函数图像构造函数:实现
fromGraph的可行方案 当然可以实现你想要的fromGraph函数!对于有限的输入列表,完全能写出满足需求的实现,不过我们得先明确一个关键细节:当传入的参数不在给定的键值对列表中时,函数应该返回什么?毕竟Haskell的函数是全函数——它必须为所有可能的输入返回一个值,哪怕这个输入不在你的图像列表里。
下面是几种实用的实现方案,你可以根据需求选择:
方案1:找不到键时抛出错误(最直接的实现)
这个方案会把输入的键值对列表转换成一个高效的查找表(Map),然后构造一个函数:如果键存在就返回对应值,不存在就抛出明确的错误信息。
import qualified Data.Map as Map fromGraph :: (Enum a, Ord a, Show a) => [(a, b)] -> (a -> b) fromGraph pairs = \x -> case Map.lookup x graphMap of Just value -> value Nothing -> error $ "fromGraph: Key " ++ show x ++ " not present in the input graph" where graphMap = Map.fromList pairs
测试你的示例:
-- 定义测试函数 testFunc :: (Num a, Enum a, Ord a, Show a) => a -> a testFunc = fromGraph [(1,3), (2,4), (3,5)] -- 验证需求 testFunc 1 == 3 -- 结果为 True testFunc 2 == 4 -- 结果为 True testFunc 3 == 5 -- 结果为 True -- 尝试不在列表中的键会报错 testFunc 4 -- 抛出错误:fromGraph: Key 4 not present in the input graph
方案2:提供默认值(更健壮的版本)
如果你不想让函数抛出错误,可以让用户指定一个默认值,当键不存在时返回这个值:
import qualified Data.Map as Map fromGraphWithDefault :: (Enum a, Ord a) => b -> [(a, b)] -> (a -> b) fromGraphWithDefault defaultValue pairs = Map.findWithDefault defaultValue <$> Map.fromList pairs
使用示例:
-- 指定默认值为0 safeTestFunc :: (Num a, Enum a, Ord a) => a -> a safeTestFunc = fromGraphWithDefault 0 [(1,3), (2,4), (3,5)] safeTestFunc 4 -- 返回 0,不会报错
方案3:纯列表查找(无需Ord约束)
如果你不需要高效的查找(比如输入列表非常短),可以直接用列表的lookup函数,这样不需要Ord a约束,只需要Eq a(而Enum a通常会和Eq a一起实现):
fromGraphSimple :: (Enum a, Eq a, Show a) => [(a, b)] -> (a -> b) fromGraphSimple pairs = \x -> case lookup x pairs of Just value -> value Nothing -> error $ "fromGraphSimple: Key " ++ show x ++ " not found"
关键说明
- 为什么需要
Ord a?Map的查找依赖键的可比较性,所以方案1和2需要这个约束;如果用纯列表查找(方案3),只需要Eq a即可。 - 对于有限输入列表,所有方案都完全可行——你只需要根据是否容忍错误、是否需要高效查找来选择合适的实现。
内容的提问来源于stack exchange,提问作者jiplucap
相关产品推荐
相关产品推荐

