抱歉,每两年一次,我会以较小的方式涉足Haskell,然后我无法回避它。
最好只是做一个例子。
stream
所以,我想做的是创建数据类型,然后根据类中数据类型的成员身份定义两个函数。...
这可行。...
List<Employee> employees = ...;
List<Employee> employeesAfterUpdate = ListUtils.partition(employees, 20)
.parallelStream()
.peek(item -> updateAvailability(user, null, item))
.flatMap(Collection::stream)
.collect(Collectors.toList());
简单...
担心#1 ...如果删除x1和x2的类型声明,ghc会抱怨
> {-# LANGUAGE MultiParamTypeClasses #-}
> {-# LANGUAGE ScopedTypeVariables #-}
> {-# LANGUAGE AllowAmbiguousTypes #-}
> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE FlexibleContexts #-}
> class Foo a b where
> foo :: a -> b
>
> class Bar a b where
> bar :: a -> b
> data A a = A a
> data B b = B b
> instance Foo (A a) a where
> foo (A a) = a
> instance Bar (B b) b where
> bar (B b) = b
这很着急,不是很明显吗?……而这种事情将再次发生……。
如果我写
> f1 x = foo x
> f2 x = bar x
> x1 :: String
> x1 = f1 $ A "1"
> x2 :: String
> x2 = f2 $ B "1"
对我来说,这是完全合理的……ghc同意!
我问它的类型...我明白了
• Ambiguous type variable ‘b1’ arising from a use of ‘f1’
prevents the constraint ‘(Foo (A [Char]) b1)’ from being solved.
Relevant bindings include x1 :: b1 (bound at catdog.lhs:27:3)
Probable fix: use a type annotation to specify what ‘b1’ should be.
These potential instance exist:
instance Foo (A a) a -- Defined at catdog.lhs:17:12
• In the expression: f1 $ A "1"
In an equation for ‘x1’: x1 = f1 $ A "1"
|
27 | > x1 = f1 $ A "1" | ^^^^^^^^^^
我可以买。
像一个好的程序员一样,我将类型粘贴到
> f x = bar (foo x)
和“ BOOM” ...
f :: (Bar a1 b, Foo a2 a1) => a2 -> b
所以ghc告诉我它没有类型声明就推断出的类型,现在还不确定!
现在...我的头上通常有一个嵌齿轮,通过使用scala或f#或其他一些OO样式类型系统,它会向后转,我必须反过来....我发疯了吗?
答案 0 :(得分:2)
让我们再次看看您的示例:
> class Foo a b where
> foo :: a -> b
这里的问题是给定的a
可能对应多个给定的b
;例如,您可能同时拥有instance Foo Int Char
和instance Foo Int Bool
。这会导致您遇到的类型推断问题。
> f1 x = foo x
> f2 x = bar x
> x1 :: String
> x1 = f1 $ A "1"
> x2 :: String
> x2 = f2 $ B "1"
例如,在这里,您同时指定了a
和b
,因此GHC知道您在谈论instance (A String) String
。删除签名时,GHC不知道使用什么b
。您尚未定义任何其他实例,也没有定义,但是GHC不知道。
那么我们如何解决这个问题?我们使用{-# LANGUAGE FunctionalDependencies #-}
:
> class Foo a b | a -> b where
> foo :: a -> b
基本上,这告诉GHC,对于任何给定的a
,只有一个对应的b
。这样可以解决您的问题(尽管我承认我还没有测试过)。有关功能依赖性的更多信息,请参见this SO answer,它也解决了您的bar (foo x)
问题。