gpt4 book ai didi

haskell - 可变参数列表构造函数,如何默认为正确的类型并获得类型安全

转载 作者:行者123 更新时间:2023-12-04 15:03:08 27 4
gpt4 key购买 nike

这是我所拥有的:

{-# LANGUAGE MultiParamTypeClasses
, FlexibleInstances #-}

class ListResultMult r a where
lstM :: a -> [a] -> r

listM :: ListResultMult r a => a -> r
listM a = lstM a []


instance ListResultMult r a => ListResultMult (a -> r) a where
lstM a as x = lstM x $ a:as

instance ListResultMult [a] a where
lstM a as = reverse $ a:as

以下是它的工作原理:
> listM 'a' 'b' 'c' :: String
"abc"
> putStrLn $ listM 'a' 'b' 'c'
abc
> listM (1::Int) (2::Int) :: [Int]
[1,2]

这是失败的原因
> sum $ listM 1 2
No instance for (ListResultMult (a2 -> [a0]) a1) ...
> listM 1 :: [Int]
No instance for (ListResultMult [Int] a0) ...

与 printf 对比:
instance Show a => ListResultMult (IO ()) a where
lstM a as = print . reverse $ a:as

> listM "foo" "bar" -- boo
No instance for (ListResult t0 [Char]) ...
> printf "%s %s" "foo" "bar"
foo bar
> listM "foo" "bar" :: IO () -- yay
["foo","bar"]

类型不安全:
> :t listM 2 "foo"
Some weird type is actually inferred

所以这就是我想要做的:
  • 类型安全。我在定义 ListResultMult r a => ListResultMult (a -> r) a 时想和 ListResultMult [a] a ,它只允许您建立同构列表,并在您不这样做时注意到类型错误。 为什么没有呢?
  • 违约。我不知道 listM 1 :: [Int] 发生了什么奇怪的事情. 这是怎么回事?
  • 最佳答案

    类型函数似乎只是解决这个问题的原因。这是一个示例文件:

    {-# LANGUAGE TypeFamilies #-}

    class ListResultMult r where
    type Elem r
    lstM :: Elem r -> [Elem r] -> r

    listM a = lstM a []

    instance (ListResultMult r, Elem r ~ a) => ListResultMult (a -> r) where
    type Elem (a -> r) = a
    lstM a as x = lstM x (a:as)

    instance ListResultMult [a] where
    type Elem [a] = a
    lstM a as = reverse (a:as)

    这是您在 ghci 中的示例:
    *Main> listM 'a' 'b' 'c' :: String
    "abc"
    *Main> putStrLn $ listM 'a' 'b' 'c'
    abc
    *Main> listM 1 2 :: [Int]
    [1,2]
    *Main> sum $ listM 1 2
    3
    *Main> listM 1 :: [Int]
    [1]
    *Main> :t listM 'a' True

    <interactive>:1:7:
    Couldn't match type `Bool' with `Char'
    In the first argument of `listM', namely 'a'
    In the expression: listM 'a' True
    *Main> :t listM 2 "foo"

    <interactive>:1:7:
    No instance for (Num [Char])
    arising from the literal `2'
    Possible fix: add an instance declaration for (Num [Char])
    In the first argument of `listM', namely `2'
    In the expression: listM 2 "foo"

    关于haskell - 可变参数列表构造函数,如何默认为正确的类型并获得类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8031288/

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