gpt4 book ai didi

haskell - foldMap 回调中强制的意外行为

转载 作者:行者123 更新时间:2023-12-04 11:54:48 30 4
gpt4 key购买 nike

这段代码编译:

import Data.List (isPrefixOf)
import Data.Monoid (Any(..))
import Data.Coerce

isRoot :: String -> Bool
isRoot path = getAny $ foldMap (coerce . isPrefixOf) ["src", "lib"] $ path

我正在使用 coerce作为包装 isPrefixOf 最终结果的快捷方式在 Any .

这个类似的代码无法编译(注意缺少 .):

isRoot :: String -> Bool
isRoot path = getAny $ foldMap (coerce isPrefixOf) ["src", "lib"] $ path

错误是:

* Couldn't match representation of type `a0' with that of `Char'
arising from a use of `coerce'
* In the first argument of `foldMap', namely `(coerce isPrefixOf)'
In the first argument of `($)', namely
`foldMap (coerce isPrefixOf) ["src", "lib"]'
In the second argument of `($)', namely
`foldMap (coerce isPrefixOf) ["src", "lib"] $ path'

但我的直觉是它也应该编译。毕竟,我们知道 isPrefixOf 的参数将是 Strings,并且结果必须是 Any 类型。没有歧义。所以 String -> String -> Bool 应该被转换成 String -> String -> Any。为什么它不起作用?

最佳答案

这与强制无关。这只是一般的约束解决。考虑:

class Foo a b
instance Foo (String -> Bool) (String -> Any)
instance Foo (String -> String -> Bool) (String -> String -> Any)

foo :: Foo a b => a -> b
foo = undefined

bar :: String -> String -> Any
bar = foo . isPrefixOf

baz :: String -> String -> Any
baz = foo isPrefixOf

bar 的定义可以正常工作; baz 的定义失败。

bar中,isPrefixOf的类型可以直接推断为String -> String -> Bool,只需统一bar的第一个参数(即String),第一个参数类型为isPrefixOf

baz 中,无法从表达式foo isPrefixOf 推断出isPrefixOf 的类型。 foo 函数可以对 isPrefix 的类型做任何事情来得到结果类型 String -> String -> Any

请记住,约束并不会真正影响类型统一。统一就像没有约束一样发生,当统一完成时,需要约束。

回到你原来的例子,下面是一个完全有效的强制,所以歧义是真实的:

{-# LANGUAGE TypeApplications #-}

import Data.Char
import Data.List (isPrefixOf)
import Data.Monoid (Any(..))
import Data.Coerce

newtype CaselessChar = CaselessChar Char
instance Eq CaselessChar where CaselessChar x == CaselessChar y = toUpper x == toUpper y

isRoot :: String -> Bool
isRoot path = getAny $ foldMap (coerce (isPrefixOf @CaselessChar)) ["src", "lib"] $ path

关于haskell - foldMap 回调中强制的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68154086/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com