我正在学习Jason Hickey的Objective Caml简介.
有这样的练习:
练习4.3假设我们有一个基于以下替换密码的加密系统,其中每个普通字母都根据下表加密.
Run Code Online (Sandbox Code Playgroud)Plain | A B C D -------------------- Encrypted | C A D B例如,字符串
BAD将被加密为ACB.编写一个函数
check,给定一个明文字符串s 1和一个密文字符串s 2,true当且仅当s 2是s 1的密文时才返回.如果s 1不是明文字符串,则您的函数应引发异常.您可能希望参考第8页的字符串操作.当字母表变大时,您的代码如何缩放?[强调补充]
基本上,我用might-be-stupid-naive这个练习的方法编写了两个函数.
我想首先就我的解决方案征求意见.
然后,我想询问练习中突出显示的缩放解决方案的提示.
let check_cipher_1 s1 s2 =
let len1 = String.length s1 in
let len2 = String.length s2 in
if len1 = len2 then
let rec check pos …Run Code Online (Sandbox Code Playgroud) 假设我想要列出列表中的所有元素,但不包括第一个负数,并返回数字和列表的其余部分.这样做的简单方法是
addPos l = s `seq` (s,back)
where
(front, back) = span (>= 0) l
s = sum front
其中,seq应确保没有人意外通过强制和前背部建立一个巨大的thunk.
然而,我很好奇GHC是否足够智能以避免创建中间前沿列表.此外,有人可以解释(如果有的话)它会发现它可以严格累积总和吗?Prelude定义使用foldl而不是foldl',GHC定义看起来相同.
在我今天编辑它之前,Haskell Wiki 声称这Maybe是一个可交换的monad(实际上,我认为它仍然在某个地方声称它).这显然是错误的,因为
do {a <- Nothing; b <- undefined; return (a,b)} === Nothing
Run Code Online (Sandbox Code Playgroud)
而
do {b <- undefined; a <- Nothing; return (a,b)} === undefined
Run Code Online (Sandbox Code Playgroud)
这种交换失败在实际代码中实际上相当重要:程序员依赖于计算一到达就会停止的事实Nothing.
这留下(在Haskell Wiki上被描述为可交换的Readermonad中)只有monad,它似乎没有做任何非常令人兴奋的事情.这引发了是否有哈斯克尔任何交换单子是基本上不同于在我脑海里的问题Reader,除了限制的 Reader.
我只是意识到也可以使受限制的Writermonad成为可交换的 - 它需要在一些可交换的monoid中积累值.仍然没有意思.
我是初学者 - 中级自学Python开发人员,
在我完成的大多数项目中,我可以看到以下过程重复.我没有任何外部家庭代码经验,我认为下面的代码不是那么专业,因为它不可重复使用,似乎它不适合容器中的所有功能,而是在不同模块上的松散耦合功能.
def get_query():
# returns the query string
pass
def make_request(query):
# makes and returns the request with query
pass
def make_api_call(request):
# calls the api and returns response
pass
def process_response(response):
# process the response and returns the details
pass
def populate_database(details):
# populates the database with the details and returns the status of population
pass
def log_status(status):
# logs the status so that developer knows whats happening
pass
query = get_query()
request = make_request(query)
response …Run Code Online (Sandbox Code Playgroud) 在依赖类型编程中定义似乎是常规的
data Vec :: Type -> Nat -> Type where
Nil :: Vec a 'Z
Cons :: a -> Vec a n -> Vec a ('S n)
Run Code Online (Sandbox Code Playgroud)
在Haskell,但是,Functor,Applicative,Foldable,Traversable,Eq1,Ord1,等,班似乎有一个良好的情况下,周边的翻转参数,来Vec :: Nat -> Type -> Type.
通常惯例有一些重要原因吗?或者它恰好是人们碰巧在不基于类型类的语言中使用的?
我正在尝试编写一个Erasthosthenes函数的筛子,它将用户的所有素数从2增加到他的上限.所以我写了这段代码:
main = do
putStrLn "Upper Limit"
g <- readLn
let sieve [] = []
let sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
let primes = sieve [2..g]
print primes
Run Code Online (Sandbox Code Playgroud)
代码编译并给我正确的解决方案,但我在解决方案的最后得到了这个例外:***例外:功能筛的非详尽模式所以我检查了哪些模式不匹配.
warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `sieve': Patterns not matched: (_:_)
warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `sieve': Patterns not matched: []
Run Code Online (Sandbox Code Playgroud)
至极我不明白,因为我已经给了let sieve [] = []
我以为_哈斯克尔是指任何变量,这样是什么模式(:)是什么意思?任何帮助,将不胜感激.
最近,我正在玩Haskell monad并试图了解这个概念.
假设声明了一个可以有多个子树的树数据类型.
data MyTree a = MyTree a [MyTree a]
Run Code Online (Sandbox Code Playgroud)
而且我正在尝试实现一个函数,如果树在树中包含任何"Nothing"值,则返回"Nothing".否则,提取所有m值并返回一个包装树.
因此函数类型签名具有以下内容.
check :: Monad m => MyTree (m a) -> m (MyTree a)
Run Code Online (Sandbox Code Playgroud)
这是我目前的实施.
check (MyTree v []) = v >>= (\v' -> return (MyTree v' []))
check (MyTree v (x:xs)) =
v >>= (\v' -> check x >>= (\t' -> return (MyTree v' [t'])))
Run Code Online (Sandbox Code Playgroud)
我在v上使用绑定运算符,以便我可以得到它的纯值.然后我用列表中的头部值递归调用"check"函数.最后,我将最终结果包装好.
我测试了一些样品并得到了以下结果.
> test1 = MyTree (Just 1) [MyTree (Just 2) [MyTree (Just 3) []]]
> check test1
Just (MyTree 1 [MyTree 2 …Run Code Online (Sandbox Code Playgroud) 对于练习我需要反转图形(反转所有边缘),但我没有得到任何结果.所以我需要一些帮助.
我知道你可能不想为我解决这个问题,所以这不是我要求的.我只需要一些建议......
所以要达到它:
data Graph a = G
{ nodes :: [a]
, successors :: a -> [a] }
reverseGraph :: Eq a => Graph a -> Graph a
Run Code Online (Sandbox Code Playgroud)
图表必须包含以下参数:节点列表和定义后继者的函数.此函数具有以下类型:
a -> [a]
例如:
graph1 :: Graph Int
graph1 = G [1..6] $ \case 1 -> [2,3]
2 -> []
3 -> [1,4,6]
4 -> [1]
5 -> [3,5]
6 -> [2,4,5]
Run Code Online (Sandbox Code Playgroud)
反转图表将是:
reverseGraph graph1 ~>
2 -> [1,6]
3 -> [1,5]
1 -> [3,4]
4 -> [3,6]
6 -> …Run Code Online (Sandbox Code Playgroud) Daniel Wagner 的评论使我想到了这个问题。让我们从过度简化开始。假设你有一个类型
data Foo a = Foo [a]
Run Code Online (Sandbox Code Playgroud)
然后您可以编写Functor实例
instance Functor Foo where
fmap f (Foo l) = Foo (fmap f l)
Run Code Online (Sandbox Code Playgroud)
您可以将右侧重写为
Foo . fmap f $ l
Run Code Online (Sandbox Code Playgroud)
认识到了(->) a,fmap = (.)你可以把它写
fmap Foo (fmap f) l
Run Code Online (Sandbox Code Playgroud)
重复,你得到
fmap (fmap Foo) fmap f l
Run Code Online (Sandbox Code Playgroud)
所以,最后,
fmap f (Foo l) =
fmap fmap fmap Foo fmap f l
Run Code Online (Sandbox Code Playgroud)
如果选择一个稍微复杂一点的函子怎么办?
data Bar = Bar [Maybe a]
instance Functor Bar where
fmap f …Run Code Online (Sandbox Code Playgroud) 我试图实现一个表示无限动作链的 monad 转换器,如下所示:
import Control.Arrow
import Control.Monad
import Data.Functor.Classes
import Data.Functor.Identity
import Data.Monoid
import Data.Semigroup
import Text.Read
import qualified Control.Monad.Trans.Class as T
newtype WhileT m a = WhileT {uncons :: m (a, WhileT m a)}
instance T.MonadTrans WhileT where
lift m = WhileT $ do
x <- m
pure (x, T.lift m)
headW :: Functor m => WhileT m a -> m a
headW (WhileT m) = fmap fst m
tailW :: Functor m => WhileT m a -> m …Run Code Online (Sandbox Code Playgroud) haskell ×8
monads ×3
class-design ×1
exception ×1
fold ×1
ghc ×1
ghci ×1
graph ×1
ocaml ×1
oop ×1
optimization ×1
python ×1
while-loop ×1