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

Haskell中如何编写接收值与类型参数的函数?

Great question! In Haskell, we don't have direct syntax for passing type parameters like your pseudocode f x T, but we can achieve exactly what you want using the TypeApplications extension, paired with your existing Transform type class. Let's break this down step by step:

解决方案概述

We'll use GHC's TypeApplications extension to explicitly specify the target type T, while letting Haskell's type inference handle the rest—no need to explicitly annotate the entire expression's type.

1. Enable Required Extensions

First, add these extensions at the top of your file (they're standard, well-supported GHC extensions):

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ExplicitForAll #-}  -- Optional, but makes type parameter order explicit

2. Define the Transform Class and Instances

Let's start with your type class plus some example instances to demonstrate:

class Transform a b where
  transform :: a -> b

-- Example 1: Convert Int to String
instance Transform Int String where
  transform = show

-- Example 2: Convert Int to Bool (check if positive)
instance Transform Int Bool where
  transform = (> 0)

-- Example 3: Convert String to Int
instance Transform String Int where
  transform = read

3. Implement Function f

Your function f is essentially a wrapper for transform (you could even use transform directly if you prefer). The key is to define its type signature to let us explicitly specify the target type T:

f :: forall b a. Transform a b => a -> b
f = transform

The forall b a. clarifies the order of type parameters: b is the target type (your T), and a is the type of input x.

4. Call f (Matching Your Pseudocode f x T)

In Haskell, we use the @Type syntax to pass type parameters. Your pseudocode f x T translates directly to f @T x:

-- Convert Int 5 to String (matches pseudocode `f 5 String`)
stringResult = f @String 5  -- Value: "5"

-- Convert Int (-3) to Bool (matches pseudocode `f (-3) Bool`)
boolResult = f @Bool (-3)  -- Value: False

-- Convert String "42" to Int (matches pseudocode `f "42" Int`)
intResult = f @Int "42"  -- Value: 42

Why No Explicit Expression Type Annotation?

Haskell's type inference does the heavy lifting automatically:

  • When you specify @String as the target type b, and pass an input x of type Int, GHC automatically finds and uses the Transform Int String instance.
  • You never need to write something like stringResult :: String (though you can if you want to be explicit—it's just not required).

Bonus: Let Type Inference Do All the Work

If your code context already defines the target type, you don't even need the @T syntax! For example:

-- putStrLn expects a String, so GHC infers we need the Transform Int String instance
main = putStrLn (f 5)

This will automatically output "5" without any type annotations.

Summary
  • Use the TypeApplications extension to mimic "passing a type parameter"—your pseudocode f x T becomes f @T x in valid Haskell.
  • Haskell's type inference eliminates the need for explicit expression type annotations.
  • Keep your Transform instances well-defined to ensure the compiler can find the correct instance without ambiguity.

内容的提问来源于stack exchange,提问作者Andrey Tyukin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:48:11