有单元课吗?它会有用吗?

jbe*_*man 6 haskell

是否存在具有单个单位值的类型(此处不确定正确的术语),即具有某些预定义值的类型?

class Unit a where
    unit :: a

instance Unit () where
    unit = ()

instance Unit (Maybe a) where
    unit = Nothing
Run Code Online (Sandbox Code Playgroud)

...适用于所有Monoids,MonadPlus等

我想这个班的另一个名字可能是Default.这对我来说最近有用了两次.

可能不能令人信服的例子:

extract :: (Unit r)=> Reader r a -> a
extract r = runReader r unit
Run Code Online (Sandbox Code Playgroud)

这存在吗?别人认为它可能有用吗?

C. *_*ann 9

是的,它可能会有用.实际上,它的所有略微不兼容的版本都是有用的!这有点问题.

目前尚不清楚这样一个类甚至意味着什么,这使得实际使用起来很困难,因为不可避免地会遇到有多个默认值选择的类型,如果不能立即清楚实例提供哪一个,那么你很漂亮首先让班级失去所有好处.

几个例子:

  • 对于Monoid情况下,你当然希望单位元素为默认.但是现在你又回到了这么多类型有两个或更多敏感Monoid实例的问题.默认值是Integer0还是1?因为Monoid,标准库使用newtype包装器,但是那些是笨拙的并且难以使用包装类型 - Monoid它可以正常工作,因为你可以访问mconcat等等,但是你只能使用默认值做一些有趣的事情.

  • 对于Functor具有"空"值的类似类型,它给出了明显的默认值.这是什么MonadPlusAlternative正在做的......也有重叠Monoid,如果没记错的话至少还有一个类型,其中的三个实例是不相同的.当你有多个选择时,你会选择哪一个?考虑列表:你可以盲目追加它们,给出一个任意的Monoid,用空列表作为标识; 但是对于Monoids你也可以zipWith mappend给出一个提升的幺半群repeat mempty作为身份.许多仿函数都有类似的Monoid实例,但并不总是两者兼而有之 - 所以无论你选择哪个列表,你都会在概念上与其他一些不一致Functor!

  • 对于像()这样的单位类型,选择默认值并不困难!但是枚举呢?选择第一个构造函数是否有意义?有时,但并非总是如此.如何使用该课程的人知道吗?

  • 怎么样Bounded?如果以上都不适用,您可以使用minBound.但是上面的一些类型也可以Bounded,所以如果它们的默认值不是它们的最小值,你就会感到困惑.

基本上,有足够的重叠似乎有意义......但实际上,你在这里至少考虑了三种不同的类型,并试图统一它们可能没有最初看起来那么有用.


如果你可以把事情做得更好,并对"默认"值进行清晰,一致的语义解释,不仅仅是重新发明Monoid或其他现有的类,这样类型类很容易使用而不必停下来思考什么"默认"被选中,太棒了!但我不希望让它成功.

也就是说,任何标准类型类都没有涵盖的明显合理的案例就是单身人士().大多数时候这些都不是非常有用 - 显而易见的原因! - 这可能就是为什么没有这样的课程.但是,这样一个类非常有用的一个地方就是当你在做涉及类型级恶作剧的事情时,因为这样的类型在类型和术语级别都代表一个值 - 所以这种类型的类允许你自由地操纵类型级值,然后想出与之相关的术语,因此您可以将它传递给其他一些函数,例如,可以根据它选择一个类型类实例.出于这个原因,我在我的永久不完整的类型hackery库中一个类,例如:

class TermProxy t where 
    term :: t

-- This makes explicit the lexical pun of () having type ().
instance TermProxy () where 
    term = ()

instance (TermProxy a, TermProxy b) => TermProxy (a, b) where 
    term = (term, term)
Run Code Online (Sandbox Code Playgroud)

我怀疑这样的类在任何其他环境中都非常有用.


Tho*_*son 6

你正在寻找某种Default类型的类.虽然"默认"应该是什么的语义是值得商榷的(我建议你接受CA McCanns在那里的有价值的评论),你可以Default从一个相当常用的包中得到一个类data-default.

这堂课是:

-- | A class for types with a default value.
class Default a where
    -- | The default value for this type.
    def :: a
Run Code Online (Sandbox Code Playgroud)

  • 是的,那个"默认"类与您希望的一致.它仍然存在我提到的一些固有的混乱 - 例如,一些`Monad`实例是`return def`,而另一些则不是.所以任何具有上下文的函数,如`(Monad m,Default ma)=>`,对于不同的`Monad`来说,其行为必然会有所不同. (2认同)
  • 我发现`data-default`对配置结构等特别有用,也就是说,在应用程序的上下文中存在合理的默认值.另外,实例不会导出. (2认同)