首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变量列表构造函数,如何默认为正确的类型并获得类型安全性

变量列表构造函数,如何默认为正确的类型并获得类型安全性
EN

Stack Overflow用户
提问于 2011-11-06 23:40:18
回答 1查看 202关注 0票数 5

我要说的是:

代码语言:javascript
复制
{-# 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

下面是它的工作原理:

代码语言:javascript
复制
> listM 'a' 'b' 'c' :: String
"abc"
> putStrLn $ listM 'a' 'b' 'c'
abc
> listM (1::Int) (2::Int) :: [Int]
[1,2]

以下是它失败的原因

代码语言:javascript
复制
> sum $ listM 1 2
No instance for (ListResultMult (a2 -> [a0]) a1) ...
> listM 1 :: [Int]
No instance for (ListResultMult [Int] a0) ...

与印刷品对比:

代码语言:javascript
复制
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"]

类型不安全:

代码语言:javascript
复制
> :t listM 2 "foo"
Some weird type is actually inferred

所以我想做的是:

  • 型安全。我想,当我定义ListResultMult r a => ListResultMult (a -> r) aListResultMult [a] a时,它只允许您建立同构列表,并且注意到一个类型错误。我不知道listM 1 :: [Int]到底发生了什么怪事。up?

是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-07 00:24:26

类型函数似乎就是解决这个问题的关键。下面是一个示例文件:

代码语言:javascript
复制
{-# 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中的例子:

代码语言:javascript
复制
*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"
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8031288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档