这两个功能几乎相同:
<img onclick="imageChange(this)" style="width: 200px; cursor: pointer;" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png">
<script>
window.imageChange = function(image) {
if (image.style.width === "200px") {
image.style.width = "100px";
} else {
image.style.width = "200px";
}
}
</script>
唯一的区别在于 where 子句中定义的函数。
以下限制适用:
dig :: MappingClassifierM FileSummary IO Partitioner -> Conduit (Cluster Partitioner FileSummary) IO (Cluster Partitioner FileSummary)
dig classifier =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify classifier clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig classifier
else do
mapM_ (yield . cluster) categories
dig classifier
where
cluster (key, val) = Cluster (key : clusterKey) val
classify = classifyM
dig' :: BinaryClassifierM FileSummary IO -> Conduit (Cluster Partitioner FileSummary) IO (Cluster Partitioner FileSummary)
dig' classifier =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify classifier clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig' classifier
else do
mapM_ (yield . cluster) categories
dig' classifier
where
cluster = Cluster (Content : clusterKey)
classify = classifyBinary
函数取决于作为第一个参数传递的分类器的“类型”。classify
函数取决于分类器的实际实现。我想概括这两个函数,以便创建一个处理两个实现的单个函数,以避免重复。
我不知道我是否朝着正确的方向前进。基于我迄今为止对Haskell的有限知识,我认为我必须创建一个类“Classifier”,BinaryClassifier和MappingClassifierM将成为其实例,但是当我尝试实现它时,我面临着几个编译错误
所以,我的问题是:经验丰富的Haskell程序员如何概括这两个函数以避免重复?
对于其他上下文,下面是我试图概括的两种不同情况的相关类型签名:
cluster
答案 0 :(得分:1)
我的方法是让编译器为我做大部分的思考。首先,我使用了公共代码并使其成为自己的函数
dig'' classifier =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify classifier clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig'' classifier
else do
mapM_ (yield . cluster) categories
dig'' classifier
这会导致一些问题。首先,编译器抱怨cluster
和classify
未定义,因此我们需要将它们作为参数添加到函数中。您还会注意到分类器从不在分类函数之外使用,因此我们将它们组合成一个值。此外,由于我们已经更改了函数的参数,我们的递归调用会发生变化,因此我们需要处理这些调用。
dig'' cluster =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig'' cluster classify
else do
mapM_ (yield . cluster) categories
dig'' cluster classify
这里我注意到where子句中的cluster
需要clusterKey
,因此它需要以某种方式作为参数传递。
dig'' cluster =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig'' cluster classify
else do
mapM_ (yield . cluster clusterKey) categories
dig'' cluster classify
最后,使用类型孔让ghc为我找出数据类型。
dig'' :: _
dig'' cluster =
await >>= \case
Nothing -> return ()
Just ( Cluster clusterKey clusterValue ) -> do
categories <- liftIO $ classify clusterValue
if (length clusterValue == length categories)
then do
yield $ Cluster clusterKey clusterValue
dig'' cluster classify
else do
mapM_ (yield . cluster clusterKey) categories
dig'' cluster classify
我的值为
(Foldable t, MonadIO m) =>
([a] -> a1 -> Cluster a b)
-> ([b] -> IO (t a1)) -> Conduit (Cluster a b) m (Cluster a b)
但是您的结果可能会有所不同,因为我主要编写了所有数据类型。例如,我怀疑代码的[a]
和[b]
会有所不同。
现在,回到原来的功能。在这里,我们的优势在于我们已经知道了结果的类型。
dig :: MappingClassifierM FileSummary IO Partitioner -> Conduit (Cluster Partitioner FileSummary) IO (Cluster Partitioner FileSummary)
dig classifier = dig'' ????
现在我们只需要dig''
的两个参数。第一个参数只是填入cluster
定义,所以我们得到
(\clusterKey (key, val) -> Cluster (key : clusterKey) val)
第二个参数是classify,我们在分类器中滚动,所以它很简单 (classifyM分类器)
因此,最终的定义是
dig :: MappingClassifierM FileSummary IO Partitioner -> Conduit (Cluster Partitioner FileSummary) IO (Cluster Partitioner FileSummary)
dig classifier = dig'' (\clusterKey (key, val) -> Cluster (key : clusterKey) val) (classifyM classifier)
同样,您也可以找到
dig' :: BinaryClassifierM FileSummary IO -> Conduit (Cluster Partitioner FileSummary) IO (Cluster Partitioner FileSummary)
dig' classifier = dig'' (\clusterKey -> Cluster (Content : clusterKey)) (classifyBinary classifier)
答案 1 :(得分:1)
我能够使用允许某些语言扩展的类找到替代解决方案:
N