Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在lambdas或函数组合(没有中间函数)中有任何消除歧义的方法吗?_Haskell - Fatal编程技术网

Haskell 在lambdas或函数组合(没有中间函数)中有任何消除歧义的方法吗?

Haskell 在lambdas或函数组合(没有中间函数)中有任何消除歧义的方法吗?,haskell,Haskell,考虑以下代码 {-# LANGUAGE DuplicateRecordFields #-} data Human = Human {name :: String } deriving (Show , Eq) data Dog = Dog {name :: String } deriving (Show , Eq) humans = [Human "bob" , Human "john", Human "paul"] -- Working humanName h = name (h :: Hu

考虑以下代码

{-# LANGUAGE DuplicateRecordFields #-}
data Human = Human {name :: String } deriving (Show , Eq)
data Dog = Dog {name :: String } deriving (Show , Eq)

humans = [Human "bob" , Human "john", Human "paul"]

-- Working
humanName h = name (h :: Human)
fh = filter ( (=="bob").humanName ) humans  
fh' = filter (\h -> (humanName h )=="bob"  ) humans  

-- Ambigous, not compiling
fh2 = filter ( (=="bob").name ) humans
-- Ambigous, not compiling
fh3 = filter (\h -> (name h )=="bob"  ) humans

-- Not compiling, I don't know if it's an error syntax or if this is impossible
fh4 = filter (\h -> (name h)=="bob" (h :: Human) ) humans

有没有办法让fh2、fh3或fh4工作,而不必定义一个用于消除歧义的命名函数

由于
name
是一个重复的记录字段,您需要指定应用该字段的类型:

fh3 = filter (\h -> (name (h::Human))=="bob") humans
有关更多信息,请参阅

编辑 否则,在处理重复的记录字段时,我希望按照以下步骤进行处理

{-# LANGUAGE DuplicateRecordFields #-}
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name
那你就可以了

filter (\h -> (name h == "bob")) humans

由于
name
是一个重复的记录字段,因此您需要指定应用该字段的类型:

fh3 = filter (\h -> (name (h::Human))=="bob") humans
有关更多信息,请参阅

编辑 否则,在处理重复的记录字段时,我希望按照以下步骤进行处理

{-# LANGUAGE DuplicateRecordFields #-}
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name
那你就可以了

filter (\h -> (name h == "bob")) humans

添加到@StéphaneLaurent的答案中,使用可以帮助实现无点风格:

{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-} 
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name

humans = [Human "bob" , Human "john", Human "paul"]

-- Now you can write it in pointfree style:
fh2 = filter ((=="Bob") . name @Human) humans
--                             ^^^^^^ This is a type argument!

添加到@StéphaneLaurent的答案中,使用可以帮助实现无点风格:

{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-} 
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name

humans = [Human "bob" , Human "john", Human "paul"]

-- Now you can write it in pointfree style:
fh2 = filter ((=="Bob") . name @Human) humans
--                             ^^^^^^ This is a type argument!

为什么不为所有这些函数添加类型签名?比如:

fh :: [Human] -> [Human]

添加类型签名应强制编译器选择正确的版本

为什么不为所有这些函数添加类型签名?比如:

fh :: [Human] -> [Human]

添加类型签名应强制编译器选择正确的版本

如果我理解正确,你可以使用
\(Human n)->n==“bob”
,但是你的
fh4
在语法上是无效的。那么
fh3=filter(\h->(name(h::Human))==“bob”)Human
呢?我将编辑我的问题;实际上,我们的想法是,在每个数据类型中有更多的字段,我不能直接在类型上使用(=),但必须使用的name函数them@sandwood:您使用
DuplicateRecordFields
扩展名,而不使用
humanName
dogName
声明记录,有什么特殊原因吗,等等?@WillemVanOnsem:是的,我做了一个真正的mcve,剥离了整个画面:简短:我做了一些数据库表到Haskell数据类型(Haskell根据实际数据库生成代码,将一个表映射到Haskell数据类型,每个数据库列有一条记录)。在这个数据库中,我有数百个表,您可以想象,我有几个表具有相同的列名(如“id”、“name”、…)。我不想用表名作为所有表名的前缀,因为我希望表名简单且最接近数据库中的真实列名。如果我理解正确,您可以使用
\(Human n)->n==“bob”
,但是您的
fh4
在语法上无效。那么
fh3=过滤器(\h->(name(h::Human))==“bob”)呢人类
?我将编辑我的问题;实际上,我们的想法是,在每个数据类型中有更多的字段,我不能直接在类型上使用(=),但必须使用的name函数them@sandwood:您使用
DuplicateRecordFields
扩展名,而不使用
humanName
dogName
声明记录,有什么特殊原因吗,等等?@WillemVanOnsem:是的,我做了一个真正的mcve,剥离了整个画面:简短:我做了一些数据库表到Haskell数据类型(Haskell根据实际数据库生成代码,将一个表映射到Haskell数据类型,每个数据库列有一条记录)。在这个数据库中,我有数百个表,您可以想象,我有几个表具有相同的列名(如“id”、“name”、…)。我不想用表名作为所有表名的前缀,因为我希望表名保持简单,并且最接近数据库中的实际列名