gpt4 book ai didi

haskell - 列出附加元素的 monad 实例

转载 作者:行者123 更新时间:2023-12-02 14:40:51 26 4
gpt4 key购买 nike

是否可以制作一个像这样工作的 Monad 实例?

foo = do
[1]
[2]
[3]

main = print foo -- prints [1,2,3]

为了实现这项工作,我需要一个约束,即每个数组都具有相同的类型:[Int]

最佳答案

你可以使用mtlWriter monad获得你想要的效果,而且没什么疯狂的:

type AutoList a = Writer [a] ()

foo :: AutoList Int
foo = do
tell [1]
tell [2]
tell [3]

toList :: AutoList a -> [a]
toList = execWriter

main = print (toList foo)

但是,您可以使用 -XOverloadedLists 进行一次可怕的黑客攻击,以仅使用列表文字来获取它。需要注意的是,您必须在每一行上给出类型签名:

{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module AutoList where

import GHC.Exts
import Control.Applicative
import Control.Monad.Writer

newtype AutoListM a r = AutoListM (Writer [a] r) deriving (Functor, Applicative, Monad)

type AutoList a = AutoListM a ()

instance IsList (AutoList a) where
type Item (AutoList a) = a
fromList = AutoListM . tell
fromListN n = AutoListM . tell . take n
toList (AutoListM w) = execWriter w


foo :: AutoList Int
foo = do
[1] :: AutoList Int
[2] :: AutoList Int
[3] :: AutoList Int


main = print (toList foo)

它必须是 do 表示法的 monad,但是如果没有类型签名,它无法确定它应该是 AutoListM Int r 中的 r ~ () >。使用显式类型签名,它可以解决所有问题,但我怀疑这是否是您真正想要的解决方案,并且它比仅使用 Writer 和tell 需要更多工作。而且,这只是你不应该做的事情。

关于haskell - 列出附加元素的 monad 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36894975/

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