質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Q&A

解決済

1回答

688閲覧

where式の後に処理を書きたい

apo

総合スコア349

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

0グッド

0クリップ

投稿2021/04/13 02:06

前提・実現したいこと

where式を使った後に処理を書きたいのですが、エラーになります。

データベースを表示するプログラムを書いていて、その後に処理を書こうとしたらエラーになりました。

発生している問題・エラーメッセージ

/home/apo/Documents/project/make/haskell/where/my-project/app/Main.hs:39:5: error: parse error on input ‘print’ | 39 | print "hello" | ^^^^^ -- While building package my-project-0.1.0.0 (scroll up to its section to see the error) using: /home/apo/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-2.0.1.0 build lib:my-project exe:my-project-exe --ghc-options " -fdiagnostics-color=always" Process exited with code: ExitFailure 1

該当のソースコード

Haskell

1{-# LANGUAGE OverloadedStrings #-} 2 3module Main where 4 5import Lib 6import Database.MySQL.Base 7import qualified System.IO.Streams as Streams 8import qualified Data.Text.IO as T 9import Data.Text 10 11main :: IO () 12main = do 13 print "id name comment time" 14 conn <- connect 15 defaultConnectInfo {ciUser = "root", ciPassword = "Password1234!", ciDatabase = "test"} 16 (defs, is) <- query_ conn "SELECT * FROM memos" 17 --print =<< Streams.toList is 18 19 mapM_ (mapM f) =<< Streams.toList is 20 where 21 -- 受け取った引数が MySQLText の場合だけ、取り出した文字列をputStrLnする関数 22 f :: MySQLValue -> IO () 23 24 f (MySQLText text) = do 25 T.putStr text 26 T.putStr " " 27 28 f (MySQLInt32 int) = do 29 T.putStr (Data.Text.pack (show int)) 30 T.putStr " " 31 32 f (MySQLDateTime text) = do 33 T.putStr (Data.Text.pack (show text)) 34 T.putStrLn "" 35 36 f _other = return () 37 38 39 print "hello"

試したこと

「print "hello"」の部分のインデントがわるいのかと思い、色々変えてみましたがダメでした。
その前の「where」及び関数「f」のインデントも色々変えてみましたがダメでした。

補足情報(FW/ツールのバージョンなど)

stack:Version 2.5.1, Git revision d6ab861544918185236cf826cb2028abb266d6d5 x86_64 hpack-0.33.0
HostPC:Windows10Pro
VirtualBox:6.1
GuestPC OS:Gentoo

すべてのソースコード
https://github.com/ringo-apo/Haskell_where

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

mapM_ (mapM f) =<< Streams.toList is のみで有効な f を定義するために where を使っているんですよね?残念ながら、wheremapM_ (mapM f) =<< Streams.toList isのようなに紐付けるものではなく、あくまでもhoge = ...のような、関数の定義に紐付ける構文なので、意図したような使い方はできません。

今回のように mapM_ (mapM f) =<< Streams.toList is のみで有効な f を定義するには、下記のように let ... in を使うしかありません:

hs

1let f :: MySQLValue -> IO () 2 3 f (MySQLText text) = do 4 -- 省略 5 6 f _other = return () 7 in mapM_ (mapM f) =<< Streams.toList is

もちろん、 f が有効な範囲を mapM_ (mapM f) =<< Streams.toList is に絞ることに強いこだわりがないなら、 let ... in ではなく do の中の letでも問題ありません(特にこの場合 mapM_ (mapM f) =<< Streams.toList isdo における最後の式なので、 do の中の let でも全く問題はないでしょう):

hs

1do 2 let f :: MySQLValue -> IO () 3 4 f (MySQLText text) = do 5 -- 省略 6 7 f _other = return () 8 mapM_ (mapM f) =<< Streams.toList is

投稿2021/04/13 02:23

編集2021/04/13 02:36
igrep

総合スコア428

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

apo

2021/04/13 02:41 編集

早速の回答、ありがとうございます。 示して頂いた2つの方法を試してみましたが、エラーになりました。 ``` /home/apo/Documents/project/make/haskell/where/my-project/app/Main.hs:33:5: error: parse error on input ‘in’ | 33 | in mapM_ (mapM f) =<< Streams.toList is | ``` ``` {-# LANGUAGE OverloadedStrings #-} module Main where import Lib import Database.MySQL.Base import qualified System.IO.Streams as Streams import qualified Data.Text.IO as T import Data.Text main :: IO () main = do print "id name comment time" conn <- connect defaultConnectInfo {ciUser = "root", ciPassword = "Password1234!", ciDatabase = "test"} (defs, is) <- query_ conn "SELECT * FROM memos" --print =<< Streams.toList is let f :: MySQLValue -> IO () f (MySQLText text) = do T.putStr text T.putStr " " f (MySQLInt32 int) = do T.putStr (Data.Text.pack (show int)) T.putStr " " f (MySQLDateTime text) = do T.putStr (Data.Text.pack (show text)) T.putStrLn "" f _other = return () in mapM_ (mapM f) =<< Streams.toList is print "hello" ``` [https://github.com/ringo-apo/Haskell_where](https://github.com/ringo-apo/Haskell_where)
igrep

2021/04/13 02:45

インデントが消えてしまっているのでこのコードからはわかりませんが、もしかして letとinの行頭がそろってしまっていませんか? let f = .. <space>in ... と、letの行頭よりinの行頭をより後ろにしなければなりません。 (という、わかりづらい問題があるのでlet ... inを進めたのは失敗でした...)
apo

2021/04/13 02:45

「in」を抜いたらできました。 ``` let f :: MySQLValue -> IO () f (MySQLText text) = do T.putStr text T.putStr " " f (MySQLInt32 int) = do T.putStr (Data.Text.pack (show int)) T.putStr " " f (MySQLDateTime text) = do T.putStr (Data.Text.pack (show text)) T.putStrLn "" f _other = return () mapM_ (mapM f) =<< Streams.toList is ``` [https://github.com/ringo-apo/Haskell_where](https://github.com/ringo-apo/Haskell_where) ありがとうございます!
apo

2021/04/13 02:52

まだまだ基本がわかっていません。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問