You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中如何通过GHC扩展自动推导带默认实现的Bar IO实例?

Solution: Using FlexibleInstances for Generic Instance Derivation

In Haskell, there isn't an extension that automatically derives the Bar IO instance without any extra code just because Foo IO exists, but you can get the behavior you want using the FlexibleInstances extension. Here's how to do it:

Step 1: Enable the FlexibleInstances Extension

Add this line at the very top of your Haskell file:

{-# LANGUAGE FlexibleInstances #-}

Step 2: Add a Generic Bar Instance

Since all methods of Bar have default implementations that rely on its superclass Foo, you can write a generic instance that applies to any type m which already has a Foo instance:

instance Foo m => Bar m where
  -- No need to define `bar` here—the default implementation from the class definition will be used automatically

Updated Working Code

Putting it all together, your code will compile successfully without needing an explicit Bar IO instance:

{-# LANGUAGE FlexibleInstances #-}

class Foo m where
  foo :: String -> m Int

class (Foo m) => Bar m where
  bar :: String -> m Int
  bar id = foo id

instance Foo IO where
  foo _ = return 0

-- Generic instance: any type with a Foo instance automatically gets a Bar instance
instance Foo m => Bar m where

quux :: IO Int
quux = foo ""

baz :: IO Int
baz = bar ""

When you call bar "" in baz, GHC resolves the Bar IO instance via the generic Foo m => Bar m declaration, since IO already has a valid Foo instance.

Handling Overlapping Instances (Optional)

If you later want to define a custom Bar instance for a specific type that overrides the generic one, enable the OverlappingInstances extension. For example:

{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}

-- Generic fallback instance
instance Foo m => Bar m where

-- Custom Bar instance for IO that overrides the generic one
instance Bar IO where
  bar _ = return 42

Just be careful with OverlappingInstances—it can introduce ambiguity if not used intentionally, so only enable it when you explicitly need this behavior.

Key Note vs. Scala Implicits

Unlike Scala's implicits, which can implicitly derive instances from superclasses, Haskell's type class system relies on explicit instance declarations. The generic instance approach using FlexibleInstances mimics the Scala behavior by explicitly stating that any Foo instance should also be a Bar instance using the default method implementations.

内容的提问来源于stack exchange,提问作者Piotr Jander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:12:32