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

Haskell技术问题:如何将[(Char, Int)]元组列表写入文本文件?

Haskell 元音计数写入文件问题修复

问题场景

读取input.txt文本内容,统计其中元音字母(大小写aeyioAEYIO)的出现次数,得到[(Char, Int)]类型的元组列表,期望每行显示一个字母与对应计数并写入output.txt,但代码运行报错。

原代码

import Data.List
import Char

add :: Eq a => a -> [(a, Int)] -> [(a, Int)]
add x [] = [(x, 1)]
add x ((y, n):rest) = if x == y
    then (y, n+1) : rest
    else (y, n) : add x rest
 
count :: Eq a => [a] -> [(a, Int)]
count = sortBy f . foldr add [] where
    f (_, x) (_, y) = compare y x

ff x = filter (\x->elem (fst x) "aeyioAEYIO") x

fff x = ff (count x)

main :: IO ()
main = do
   src <- readFile "input.txt"
   writeFile "output.txt" (operate src)

operate :: [(Char, Int)] -> String
operate = fff

报错信息

*** Term           : operate
*** Type           : [Char] -> [(Char,Int)]
*** Does not match : [(Char,Int)] -> String

错误原因

核心问题是类型不匹配:

  • fff函数的实际类型是[Char] -> [(Char, Int)](接收字符串,返回计数元组列表)
  • 你给operate标注的类型是[(Char, Int)] -> String(接收元组列表,返回字符串),但代码里把operate直接绑定成了fff,导致类型完全反转。
  • 另外,writeFile要求传入String类型参数,但原代码直接传递元组列表,就算类型问题解决,也无法直接将元组转换为可写入的文本格式。

修复步骤

  1. 修正operate的类型定义,让它接收字符串并返回格式化后的可写入字符串。
  2. 添加元组转字符串的逻辑,把每个(Char, Int)元组转换成"字母: 次数\n"的格式,再拼接成完整文本。
  3. 替换过时的Char模块导入为Data.Char,适配现代GHC版本。

修正后代码

import Data.List
import Data.Char

add :: Eq a => a -> [(a, Int)] -> [(a, Int)]
add x [] = [(x, 1)]
add x ((y, n):rest) = if x == y
    then (y, n+1) : rest
    else (y, n) : add x rest
 
count :: Eq a => [a] -> [(a, Int)]
count = sortBy f . foldr add [] where
    f (_, x) (_, y) = compare y x

filterVowels :: [(Char, Int)] -> [(Char, Int)]
filterVowels = filter (\(c, _) -> elem c "aeyioAEYIO")

countVowels :: String -> [(Char, Int)]
countVowels = filterVowels . count

-- 将元组列表格式化为每行一个条目
formatResults :: [(Char, Int)] -> String
formatResults = unlines . map (\(c, n) -> c : ": " ++ show n)

operate :: String -> String
operate = formatResults . countVowels

main :: IO ()
main = do
   src <- readFile "input.txt"
   writeFile "output.txt" (operate src)

关键修正说明

  • 重命名了原有的ff、fff函数为更具语义的filterVowels、countVowels,提升代码可读性。
  • formatResults函数用map转换每个元组为字符串,再通过unlines自动添加换行符,满足每行一个条目的需求。
  • 修正后的operate会先完成元音统计,再将结果格式化为可直接写入文件的字符串。
  • 替换import Char为import Data.Char,避免旧模块带来的编译警告。

内容的提问来源于stack exchange,提问作者Clark Brown

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:20:34